mirror of
https://github.com/CrispyPin/sinpin-vr.git
synced 2024-11-10 04:20:25 +01:00
Compare commits
No commits in common. "b00dab62dbc1fddd7d6d203583fc38be7ff05a50" and "809edb810e1b0831f43df81f5a26097d65725099" have entirely different histories.
b00dab62db
...
809edb810e
11 changed files with 171 additions and 377 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1 @@
|
||||||
overlay
|
overlay
|
||||||
.vscode/
|
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -1,17 +1,7 @@
|
||||||
|
|
||||||
# CC := g++
|
|
||||||
CC := clang++
|
|
||||||
LFLAGS := -lX11 -lXrandr -lglfw -lGL
|
|
||||||
LIBS := openvr/libopenvr_api.so
|
|
||||||
SRC := src/*.cpp
|
|
||||||
OUT := ./overlay
|
|
||||||
CPPFLAGS := -Wall -std=c++17 $(LFLAGS) $(LIBS) $(SRC) -o $(OUT)
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(CC) -g $(CPPFLAGS)
|
g++ -Wall -lX11 -lXrandr -lglfw -lGL openvr/libopenvr_api.so src/*.cpp -o overlay
|
||||||
|
|
||||||
release:
|
|
||||||
$(CC) $(CPPFLAGS)
|
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
./overlay
|
./overlay
|
||||||
|
|
49
src/app.cpp
49
src/app.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
#include "panel.h"
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
@ -9,7 +10,6 @@ App::App()
|
||||||
InitOVR();
|
InitOVR();
|
||||||
InitX11();
|
InitX11();
|
||||||
InitGLFW();
|
InitGLFW();
|
||||||
InitRootOverlay();
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
glGenTextures(1, &_gl_frame);
|
glGenTextures(1, &_gl_frame);
|
||||||
|
@ -21,23 +21,18 @@ App::App()
|
||||||
printf("found %d monitors:\n", monitor_count);
|
printf("found %d monitors:\n", monitor_count);
|
||||||
|
|
||||||
float pixels_per_meter = 1920;
|
float pixels_per_meter = 1920;
|
||||||
float total_width_meters = _root_width / pixels_per_meter;
|
float x_min = -(monitor_info[0].x + monitor_info[0].width / 2.0f);
|
||||||
float total_height_meters = _root_height / pixels_per_meter;
|
// float x_min = _root_width / -2.0f;
|
||||||
|
|
||||||
for (int i = 0; i < monitor_count; i++)
|
for (int i = 0; i < monitor_count; i++)
|
||||||
{
|
{
|
||||||
XRRMonitorInfo mon = monitor_info[i];
|
XRRMonitorInfo mon = monitor_info[i];
|
||||||
printf("screen %d: pos(%d, %d) %dx%d\n", i, mon.x, mon.y, mon.width, mon.height);
|
printf("screen %d: pos(%d, %d) %dx%d\n", i, mon.x, mon.y, mon.width, mon.height);
|
||||||
|
|
||||||
_panels.push_back(Panel(this, i, mon.x, mon.y, mon.width, mon.height));
|
float pos_x = (x_min + mon.x) / pixels_per_meter;
|
||||||
|
float pos_y = 1.2f;
|
||||||
float width = mon.width / pixels_per_meter;
|
vr::HmdMatrix34_t start_pose = {{{1, 0, 0, pos_x}, {0, 1, 0, pos_y}, {0, 0, 1, 0}}};
|
||||||
float pos_x = mon.x / pixels_per_meter + width / 2.0f - total_width_meters / 2.0f;
|
_panels.push_back(Panel(this, start_pose, i, mon.x, mon.y, mon.width, mon.height));
|
||||||
float height = mon.height / pixels_per_meter;
|
|
||||||
float pos_y = 1.2f + mon.y / pixels_per_meter - height / 2.0f + total_height_meters / 2.0f;
|
|
||||||
VRMat start_pose = {{{1, 0, 0, pos_x}, {0, 1, 0, pos_y}, {0, 0, 1, 0}}};
|
|
||||||
_panels[i].GetOverlay()->SetTransformWorld(&start_pose);
|
|
||||||
_panels[i].GetOverlay()->SetWidth(width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // initialize SteamVR input
|
{ // initialize SteamVR input
|
||||||
|
@ -107,40 +102,11 @@ void App::InitGLFW()
|
||||||
printf("Created GLFW context\n");
|
printf("Created GLFW context\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::InitRootOverlay()
|
|
||||||
{
|
|
||||||
_root_overlay = Overlay(this, "root");
|
|
||||||
_root_overlay.SetAlpha(0.2f);
|
|
||||||
// clang-format off
|
|
||||||
VRMat root_start_pose = {{
|
|
||||||
{0.25f, 0.0f, 0.0f, 0},
|
|
||||||
{0.0f, 0.25f, 0.0f, 0.8f},
|
|
||||||
{0.0f, 0.0f, 1.0f, 0}
|
|
||||||
}};
|
|
||||||
// clang-format on
|
|
||||||
_root_overlay.SetTransformWorld(&root_start_pose);
|
|
||||||
|
|
||||||
_root_overlay._GrabBeginCallback = [this](TrackerID controller) {
|
|
||||||
for (auto &panel : _panels)
|
|
||||||
{
|
|
||||||
panel.GetOverlay()->ControllerGrab(controller);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
_root_overlay._GrabEndCallback = [this](TrackerID controller) {
|
|
||||||
for (auto &panel : _panels)
|
|
||||||
{
|
|
||||||
panel.GetOverlay()->ControllerRelease();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
printf("Created root overlay instance\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::Update()
|
void App::Update()
|
||||||
{
|
{
|
||||||
UpdateInput();
|
UpdateInput();
|
||||||
if (!_hidden)
|
if (!_hidden)
|
||||||
{
|
{
|
||||||
_root_overlay.Update();
|
|
||||||
UpdateFramebuffer();
|
UpdateFramebuffer();
|
||||||
for (auto &panel : _panels)
|
for (auto &panel : _panels)
|
||||||
{
|
{
|
||||||
|
@ -163,7 +129,6 @@ void App::UpdateInput()
|
||||||
if (IsInputJustPressed(i, _input_handles.toggle))
|
if (IsInputJustPressed(i, _input_handles.toggle))
|
||||||
{
|
{
|
||||||
_hidden = !_hidden;
|
_hidden = !_hidden;
|
||||||
_root_overlay.SetHidden(_hidden);
|
|
||||||
for (auto &panel : _panels)
|
for (auto &panel : _panels)
|
||||||
{
|
{
|
||||||
panel.SetHidden(_hidden);
|
panel.SetHidden(_hidden);
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
|
||||||
#include "overlay.h"
|
|
||||||
#include "panel.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class Panel;
|
||||||
|
|
||||||
struct CursorPos
|
struct CursorPos
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -54,7 +54,6 @@ class App
|
||||||
InputHandles _input_handles;
|
InputHandles _input_handles;
|
||||||
vr::TrackedDevicePose_t _tracker_poses[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t _tracker_poses[vr::k_unMaxTrackedDeviceCount];
|
||||||
|
|
||||||
Overlay _root_overlay;
|
|
||||||
std::vector<Panel> _panels;
|
std::vector<Panel> _panels;
|
||||||
bool _hidden = false;
|
bool _hidden = false;
|
||||||
|
|
||||||
|
@ -62,7 +61,6 @@ class App
|
||||||
void InitX11();
|
void InitX11();
|
||||||
void InitOVR();
|
void InitOVR();
|
||||||
void InitGLFW();
|
void InitGLFW();
|
||||||
void InitRootOverlay();
|
|
||||||
|
|
||||||
void UpdateFramebuffer();
|
void UpdateFramebuffer();
|
||||||
void UpdateInput();
|
void UpdateInput();
|
||||||
|
|
94
src/grab_component.cpp
Normal file
94
src/grab_component.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "grab_component.h"
|
||||||
|
|
||||||
|
GrabComponent::GrabComponent(App *app)
|
||||||
|
{
|
||||||
|
_app = app;
|
||||||
|
_is_held = false;
|
||||||
|
_active_hand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrabComponent::Update(OverlayID id, float *meters)
|
||||||
|
{
|
||||||
|
_id = id;
|
||||||
|
|
||||||
|
if (!_is_held)
|
||||||
|
{
|
||||||
|
for (auto controller : _app->GetControllers())
|
||||||
|
{
|
||||||
|
if (_app->IsInputJustPressed(controller, _app->_input_handles.grab))
|
||||||
|
{
|
||||||
|
vr::HmdMatrix34_t overlay_pose;
|
||||||
|
vr::ETrackingUniverseOrigin tracking_universe;
|
||||||
|
_app->vr_overlay->GetOverlayTransformAbsolute(id, &tracking_universe, &overlay_pose);
|
||||||
|
|
||||||
|
auto controller_pos = GetPos(_app->GetTrackerPose(controller));
|
||||||
|
|
||||||
|
auto local_pos = glm::inverse(ConvertMat(overlay_pose)) * glm::vec4(controller_pos - GetPos(overlay_pose), 0);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState)
|
||||||
|
{
|
||||||
|
ControllerRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrabComponent::IsHeld()
|
||||||
|
{
|
||||||
|
return _is_held;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackerID GrabComponent::ActiveHand()
|
||||||
|
{
|
||||||
|
return _active_hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrabComponent::ControllerGrab(TrackerID controller)
|
||||||
|
{
|
||||||
|
_is_held = true;
|
||||||
|
_active_hand = controller;
|
||||||
|
|
||||||
|
_app->vr_overlay->SetOverlayColor(_id, 0.6f, 0.8f, 0.8f);
|
||||||
|
|
||||||
|
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 GrabComponent::ControllerRelease()
|
||||||
|
{
|
||||||
|
_is_held = false;
|
||||||
|
_active_hand = -1;
|
||||||
|
|
||||||
|
_app->vr_overlay->SetOverlayColor(_id, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
23
src/grab_component.h
Normal file
23
src/grab_component.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
class GrabComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GrabComponent(App *app);
|
||||||
|
bool IsHeld();
|
||||||
|
TrackerID ActiveHand();
|
||||||
|
void Update(OverlayID id, float *meters);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ControllerRelease();
|
||||||
|
void ControllerGrab(TrackerID controller);
|
||||||
|
|
||||||
|
App *_app;
|
||||||
|
OverlayID _id;
|
||||||
|
|
||||||
|
bool _is_held;
|
||||||
|
TrackerID _active_hand;
|
||||||
|
};
|
222
src/overlay.cpp
222
src/overlay.cpp
|
@ -1,222 +0,0 @@
|
||||||
#include "overlay.h"
|
|
||||||
#include "app.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include <glm/fwd.hpp>
|
|
||||||
|
|
||||||
Overlay::Overlay()
|
|
||||||
{
|
|
||||||
_initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Overlay::Overlay(App *app, std::string name)
|
|
||||||
{
|
|
||||||
_initialized = true;
|
|
||||||
_name = name;
|
|
||||||
_app = app;
|
|
||||||
_is_held = false;
|
|
||||||
_active_hand = 0;
|
|
||||||
_width_m = 1;
|
|
||||||
|
|
||||||
_target.type = TargetType::World;
|
|
||||||
|
|
||||||
auto overlay_create_err = _app->vr_overlay->CreateOverlay(_name.c_str(), _name.c_str(), &_id);
|
|
||||||
assert(overlay_create_err == 0);
|
|
||||||
{
|
|
||||||
vr::ETrackingUniverseOrigin origin;
|
|
||||||
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &origin, &_target.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t col[4] = {20, 50, 50, 255};
|
|
||||||
_app->vr_overlay->SetOverlayRaw(_id, &col, 1, 1, 4);
|
|
||||||
printf("Created overlay instance %s\n", _name.c_str());
|
|
||||||
|
|
||||||
// (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);
|
|
||||||
SetHidden(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayID Overlay::Id()
|
|
||||||
{
|
|
||||||
return _id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Overlay::IsHeld()
|
|
||||||
{
|
|
||||||
return _is_held;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackerID Overlay::ActiveHand()
|
|
||||||
{
|
|
||||||
return _active_hand;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Overlay::IsHidden()
|
|
||||||
{
|
|
||||||
return _hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Overlay::Alpha()
|
|
||||||
{
|
|
||||||
return _alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Overlay::Width()
|
|
||||||
{
|
|
||||||
return _width_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetWidth(float width_meters)
|
|
||||||
{
|
|
||||||
_width_m = width_meters;
|
|
||||||
_app->vr_overlay->SetOverlayWidthInMeters(_id, _width_m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetHidden(bool state)
|
|
||||||
{
|
|
||||||
_hidden = state;
|
|
||||||
if (_hidden)
|
|
||||||
_app->vr_overlay->HideOverlay(_id);
|
|
||||||
else
|
|
||||||
_app->vr_overlay->ShowOverlay(_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetAlpha(float alpha)
|
|
||||||
{
|
|
||||||
_alpha = alpha;
|
|
||||||
_app->vr_overlay->SetOverlayAlpha(_id, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetTexture(vr::Texture_t *texture)
|
|
||||||
{
|
|
||||||
auto set_texture_err = _app->vr_overlay->SetOverlayTexture(_id, texture);
|
|
||||||
assert(set_texture_err == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetTransformTracker(TrackerID tracker, VRMat *transform)
|
|
||||||
{
|
|
||||||
_app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, tracker, transform);
|
|
||||||
_target.type = TargetType::Tracker;
|
|
||||||
_target.id = tracker;
|
|
||||||
_target.transform = *transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetTransformWorld(VRMat *transform)
|
|
||||||
{
|
|
||||||
_app->vr_overlay->SetOverlayTransformAbsolute(_id, vr::TrackingUniverseStanding, transform);
|
|
||||||
_target.type = TargetType::World;
|
|
||||||
_target.transform = *transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::SetTargetWorld()
|
|
||||||
{
|
|
||||||
auto abs_pose = ConvertMat(GetTransformAbsolute());
|
|
||||||
_app->vr_overlay->SetOverlayTransformAbsolute(_id, vr::TrackingUniverseStanding, &abs_pose);
|
|
||||||
_target.type = TargetType::World;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::mat4x4 Overlay::GetTransformAbsolute()
|
|
||||||
{
|
|
||||||
if (_is_held)
|
|
||||||
{
|
|
||||||
VRMat pose;
|
|
||||||
auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_active_hand, &pose);
|
|
||||||
assert(err == 0);
|
|
||||||
auto offset = ConvertMat(pose);
|
|
||||||
auto controller = _app->GetTrackerPose(_active_hand);
|
|
||||||
return controller * offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (_target.type)
|
|
||||||
{
|
|
||||||
case TargetType::World: {
|
|
||||||
VRMat pose;
|
|
||||||
vr::ETrackingUniverseOrigin tracking_universe;
|
|
||||||
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &tracking_universe, &pose);
|
|
||||||
return ConvertMat(pose);
|
|
||||||
}
|
|
||||||
case TargetType::Tracker: {
|
|
||||||
VRMat pose;
|
|
||||||
_app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_target.id, &pose);
|
|
||||||
auto offset = ConvertMat(pose);
|
|
||||||
auto tracker_pose = _app->GetTrackerPose(_target.id);
|
|
||||||
return tracker_pose * offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::Update()
|
|
||||||
{
|
|
||||||
if (!_initialized)
|
|
||||||
{
|
|
||||||
printf("Error: overlay %s is not initialized.\n", _name.c_str());
|
|
||||||
assert(_initialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_is_held)
|
|
||||||
{
|
|
||||||
for (auto controller : _app->GetControllers())
|
|
||||||
{
|
|
||||||
if (_app->IsInputJustPressed(controller, _app->_input_handles.grab))
|
|
||||||
{
|
|
||||||
auto overlay_pose = GetTransformAbsolute();
|
|
||||||
auto controller_pos = GetPos(_app->GetTrackerPose(controller));
|
|
||||||
|
|
||||||
auto local_pos = glm::inverse(overlay_pose) * glm::vec4(controller_pos - GetPos(overlay_pose), 0);
|
|
||||||
|
|
||||||
float grab_area_thickness = 0.3f;
|
|
||||||
bool close_enough = glm::abs(local_pos.z) < grab_area_thickness;
|
|
||||||
close_enough &= glm::abs(local_pos.x) < _width_m / 2.0f;
|
|
||||||
close_enough &= glm::abs(local_pos.y) < _width_m / 2.0f;
|
|
||||||
|
|
||||||
if (close_enough)
|
|
||||||
{
|
|
||||||
ControllerGrab(controller);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState)
|
|
||||||
{
|
|
||||||
ControllerRelease();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
VRMat relative_pose = ConvertMat(glm::inverse(controller_mat) * abs_mat);
|
|
||||||
|
|
||||||
_app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller, &relative_pose);
|
|
||||||
|
|
||||||
if (_GrabBeginCallback != nullptr)
|
|
||||||
{
|
|
||||||
_GrabBeginCallback(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
_is_held = true;
|
|
||||||
_active_hand = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlay::ControllerRelease()
|
|
||||||
{
|
|
||||||
_app->vr_overlay->SetOverlayColor(_id, 1.0f, 1.0f, 1.0f);
|
|
||||||
|
|
||||||
auto new_pose = ConvertMat(GetTransformAbsolute());
|
|
||||||
_app->vr_overlay->SetOverlayTransformAbsolute(_id, _app->_tracking_origin, &new_pose);
|
|
||||||
|
|
||||||
if (_GrabEndCallback != nullptr)
|
|
||||||
{
|
|
||||||
_GrabEndCallback(_active_hand);
|
|
||||||
}
|
|
||||||
_is_held = false;
|
|
||||||
_active_hand = -1;
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class App;
|
|
||||||
|
|
||||||
enum class TargetType
|
|
||||||
{
|
|
||||||
World,
|
|
||||||
Tracker,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Target
|
|
||||||
{
|
|
||||||
TargetType type;
|
|
||||||
TrackerID id;
|
|
||||||
VRMat transform;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Overlay
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Overlay();
|
|
||||||
Overlay(App *app, std::string name);
|
|
||||||
void Update();
|
|
||||||
|
|
||||||
OverlayID Id();
|
|
||||||
bool IsHeld();
|
|
||||||
bool IsHidden();
|
|
||||||
TrackerID ActiveHand();
|
|
||||||
float Width();
|
|
||||||
float Alpha();
|
|
||||||
|
|
||||||
void SetWidth(float meters);
|
|
||||||
void SetHidden(bool state);
|
|
||||||
void SetAlpha(float alpha);
|
|
||||||
void SetTexture(vr::Texture_t *texture);
|
|
||||||
|
|
||||||
void SetTransformTracker(TrackerID tracker, VRMat *transform);
|
|
||||||
void SetTransformWorld(VRMat *transform);
|
|
||||||
|
|
||||||
// void SetTargetTracker(TrackerID tracker);
|
|
||||||
void SetTargetWorld();
|
|
||||||
|
|
||||||
std::function<void(TrackerID)> _GrabBeginCallback;
|
|
||||||
std::function<void(TrackerID)> _GrabEndCallback;
|
|
||||||
|
|
||||||
void ControllerRelease();
|
|
||||||
void ControllerGrab(TrackerID controller);
|
|
||||||
|
|
||||||
private:
|
|
||||||
glm::mat4x4 GetTransformAbsolute();
|
|
||||||
|
|
||||||
bool _initialized;
|
|
||||||
|
|
||||||
App *_app;
|
|
||||||
OverlayID _id;
|
|
||||||
|
|
||||||
std::string _name;
|
|
||||||
bool _is_held;
|
|
||||||
bool _hidden;
|
|
||||||
float _width_m;
|
|
||||||
float _alpha;
|
|
||||||
TrackerID _active_hand;
|
|
||||||
|
|
||||||
Target _target;
|
|
||||||
};
|
|
|
@ -1,16 +1,18 @@
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "app.h"
|
|
||||||
#include "overlay.h"
|
|
||||||
|
|
||||||
Panel::Panel(App *app, int index, int x, int y, int width, int height)
|
Panel::Panel(App *app, vr::HmdMatrix34_t start_pose, int index, int x, int y, int width, int height)
|
||||||
: _app(app),
|
: _app(app),
|
||||||
_index(index),
|
_index(index),
|
||||||
_x(x),
|
_x(x),
|
||||||
_y(y),
|
_y(y),
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_overlay(app, "screen_view_" + std::to_string(index))
|
_grab_component(app)
|
||||||
{
|
{
|
||||||
|
_name = "screen_view_" + std::to_string(index);
|
||||||
|
_alpha = 1.0f;
|
||||||
|
_meters = 1.0f;
|
||||||
|
|
||||||
glGenTextures(1, &_gl_texture);
|
glGenTextures(1, &_gl_texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, _gl_texture);
|
glBindTexture(GL_TEXTURE_2D, _gl_texture);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
@ -23,7 +25,20 @@ Panel::Panel(App *app, int index, int x, int y, int width, int height)
|
||||||
_texture.eType = vr::TextureType_OpenGL;
|
_texture.eType = vr::TextureType_OpenGL;
|
||||||
_texture.handle = (void *)(uintptr_t)_gl_texture;
|
_texture.handle = (void *)(uintptr_t)_gl_texture;
|
||||||
|
|
||||||
// _overlay;
|
// 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);
|
||||||
|
_app->vr_overlay->SetOverlayTransformAbsolute(_id, _app->_tracking_origin, &start_pose);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::Update()
|
void Panel::Update()
|
||||||
|
@ -31,12 +46,7 @@ void Panel::Update()
|
||||||
Render();
|
Render();
|
||||||
UpdateCursor();
|
UpdateCursor();
|
||||||
|
|
||||||
_overlay.Update();
|
_grab_component.Update(_id, &_meters);
|
||||||
}
|
|
||||||
|
|
||||||
Overlay *Panel::GetOverlay()
|
|
||||||
{
|
|
||||||
return &_overlay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::Render()
|
void Panel::Render()
|
||||||
|
@ -48,12 +58,17 @@ void Panel::Render()
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
_width, _height, 1);
|
_width, _height, 1);
|
||||||
|
|
||||||
_overlay.SetTexture(&_texture);
|
auto set_texture_err = _app->vr_overlay->SetOverlayTexture(_id, &_texture);
|
||||||
|
assert(set_texture_err == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::SetHidden(bool state)
|
void Panel::SetHidden(bool state)
|
||||||
{
|
{
|
||||||
_overlay.SetHidden(state);
|
_hidden = state;
|
||||||
|
if (state)
|
||||||
|
_app->vr_overlay->HideOverlay(_id);
|
||||||
|
else
|
||||||
|
_app->vr_overlay->ShowOverlay(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::UpdateCursor()
|
void Panel::UpdateCursor()
|
||||||
|
@ -61,7 +76,7 @@ void Panel::UpdateCursor()
|
||||||
auto global_pos = _app->GetCursorPosition();
|
auto global_pos = _app->GetCursorPosition();
|
||||||
if (global_pos.x < _x || global_pos.x >= _x + _width || global_pos.y < _y || global_pos.y >= _y + _height)
|
if (global_pos.x < _x || global_pos.x >= _x + _width || global_pos.y < _y || global_pos.y >= _y + _height)
|
||||||
{
|
{
|
||||||
_app->vr_overlay->ClearOverlayCursorPositionOverride(_overlay.Id());
|
_app->vr_overlay->ClearOverlayCursorPositionOverride(_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int local_x = global_pos.x - _x;
|
int local_x = global_pos.x - _x;
|
||||||
|
@ -73,5 +88,5 @@ void Panel::UpdateCursor()
|
||||||
float x = local_x / (float)_width;
|
float x = local_x / (float)_width;
|
||||||
float y = 1.0f - (local_y / (float)_width + top_edge);
|
float y = 1.0f - (local_y / (float)_width + top_edge);
|
||||||
auto pos = vr::HmdVector2_t{x, y};
|
auto pos = vr::HmdVector2_t{x, y};
|
||||||
_app->vr_overlay->SetOverlayCursorPositionOverride(_overlay.Id(), &pos);
|
_app->vr_overlay->SetOverlayCursorPositionOverride(_id, &pos);
|
||||||
}
|
}
|
||||||
|
|
16
src/panel.h
16
src/panel.h
|
@ -1,36 +1,38 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "overlay.h"
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
|
||||||
|
#include "grab_component.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
const VRMat DEFAULT_POSE = {{{1, 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 1, 0}}};
|
const vr::HmdMatrix34_t DEFAULT_POSE = {{{1, 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 1, 0}}};
|
||||||
|
|
||||||
class App;
|
class App;
|
||||||
class Overlay;
|
|
||||||
|
|
||||||
class Panel
|
class Panel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Panel(App *app, int index, int xmin, int xmax, int ymin, int ymax);
|
Panel(App *app, vr::HmdMatrix34_t start_pose, int index, int xmin, int xmax, int ymin, int ymax);
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
void SetHidden(bool state);
|
void SetHidden(bool state);
|
||||||
|
|
||||||
Overlay *GetOverlay();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Render();
|
void Render();
|
||||||
void UpdateCursor();
|
void UpdateCursor();
|
||||||
|
|
||||||
App *_app;
|
App *_app;
|
||||||
|
OverlayID _id;
|
||||||
int _index;
|
int _index;
|
||||||
|
std::string _name;
|
||||||
|
|
||||||
int _x, _y;
|
int _x, _y;
|
||||||
int _width, _height;
|
int _width, _height;
|
||||||
|
float _meters;
|
||||||
|
float _alpha;
|
||||||
|
bool _hidden;
|
||||||
|
|
||||||
Overlay _overlay;
|
GrabComponent _grab_component;
|
||||||
|
|
||||||
vr::Texture_t _texture;
|
vr::Texture_t _texture;
|
||||||
GLuint _gl_texture;
|
GLuint _gl_texture;
|
||||||
|
|
11
src/util.h
11
src/util.h
|
@ -5,9 +5,8 @@
|
||||||
|
|
||||||
typedef vr::TrackedDeviceIndex_t TrackerID;
|
typedef vr::TrackedDeviceIndex_t TrackerID;
|
||||||
typedef vr::VROverlayHandle_t OverlayID;
|
typedef vr::VROverlayHandle_t OverlayID;
|
||||||
typedef vr::HmdMatrix34_t VRMat;
|
|
||||||
|
|
||||||
inline void PrintMat(VRMat m)
|
inline void PrintMat(vr::HmdMatrix34_t m)
|
||||||
{
|
{
|
||||||
printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[0][0], m.m[0][1], m.m[0][2], m.m[0][3]);
|
printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[0][0], m.m[0][1], m.m[0][2], m.m[0][3]);
|
||||||
printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[1][0], m.m[1][1], m.m[1][2], m.m[1][3]);
|
printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[1][0], m.m[1][1], m.m[1][2], m.m[1][3]);
|
||||||
|
@ -22,7 +21,7 @@ inline void PrintMat(glm::mat4x4 m)
|
||||||
printf("[%.2f, %.2f, %.2f, %.2f]\n", m[3][0], m[3][1], m[3][2], m[3][3]);
|
printf("[%.2f, %.2f, %.2f, %.2f]\n", m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline glm::mat4x4 ConvertMat(VRMat mat)
|
inline glm::mat4x4 ConvertMat(vr::HmdMatrix34_t mat)
|
||||||
{
|
{
|
||||||
auto m = mat.m;
|
auto m = mat.m;
|
||||||
return glm::mat4x4(
|
return glm::mat4x4(
|
||||||
|
@ -32,10 +31,10 @@ inline glm::mat4x4 ConvertMat(VRMat mat)
|
||||||
m[0][3], m[1][3], m[2][3], 1);
|
m[0][3], m[1][3], m[2][3], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VRMat ConvertMat(glm::mat4x4 m)
|
inline vr::HmdMatrix34_t ConvertMat(glm::mat4x4 m)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
return VRMat{{
|
return vr::HmdMatrix34_t{{
|
||||||
{m[0][0], m[1][0], m[2][0], m[3][0]},
|
{m[0][0], m[1][0], m[2][0], m[3][0]},
|
||||||
{m[0][1], m[1][1], m[2][1], m[3][1]},
|
{m[0][1], m[1][1], m[2][1], m[3][1]},
|
||||||
{m[0][2], m[1][2], m[2][2], m[3][2]}
|
{m[0][2], m[1][2], m[2][2], m[3][2]}
|
||||||
|
@ -48,7 +47,7 @@ inline glm::vec3 GetPos(glm::mat4x4 mat)
|
||||||
return glm::vec3(mat[3][0], mat[3][1], mat[3][2]);
|
return glm::vec3(mat[3][0], mat[3][1], mat[3][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline glm::vec3 GetPos(VRMat mat)
|
inline glm::vec3 GetPos(vr::HmdMatrix34_t mat)
|
||||||
{
|
{
|
||||||
return glm::vec3(mat.m[0][3], mat.m[1][3], mat.m[2][3]);
|
return glm::vec3(mat.m[0][3], mat.m[1][3], mat.m[2][3]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue