cleanup
This commit is contained in:
217
src/hmd.cpp
217
src/hmd.cpp
@@ -3,61 +3,28 @@
|
||||
#include "log.h"
|
||||
#include <array>
|
||||
|
||||
Vive::Vive()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
controllers[i].active = true;
|
||||
}
|
||||
|
||||
std::string Vive::ReadPropString(vr::TrackedDeviceIndex_t nDevice, vr::ETrackedDeviceProperty p)
|
||||
{
|
||||
size_t len = hmd->GetStringTrackedDeviceProperty(nDevice, p, nullptr, 0);
|
||||
std::string str(len, '\0');
|
||||
hmd->GetStringTrackedDeviceProperty(nDevice, p, (char*)str.data(), len);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool Vive::Initialize()
|
||||
{
|
||||
vr::EVRInitError error;
|
||||
hmd = vr::VR_Init(&error, vr::EVRApplicationType::VRApplication_Scene);
|
||||
m_hmd = vr::VR_Init(&error, vr::EVRApplicationType::VRApplication_Scene);
|
||||
if (error != vr::EVRInitError::VRInitError_None)
|
||||
return false;
|
||||
comp = vr::VRCompositor();
|
||||
if (!comp)
|
||||
|
||||
if (!(m_comp = vr::VRCompositor()))
|
||||
return false;
|
||||
|
||||
settings = vr::VRSettings();
|
||||
m_settings = vr::VRSettings();
|
||||
|
||||
hmd->GetRecommendedRenderTargetSize(&eyeWidth, &eyeHeight);
|
||||
LOG("Eye target resolution: %dx%d\n", eyeWidth, eyeHeight);
|
||||
m_hmd->GetRecommendedRenderTargetSize(&m_eye_width, &m_eye_height);
|
||||
for (int eye = 0; eye < 2; ++eye)
|
||||
{
|
||||
eyes[eye].create(eyeWidth, eyeHeight);
|
||||
eyes[eye].bindFramebuffer();
|
||||
eyes[eye].clear({ 1, 0, 0, 1 });
|
||||
eyes[eye].unbindFramebuffer();
|
||||
m_eyes[eye].create(m_eye_width, m_eye_height);
|
||||
m_eyes[eye].bindFramebuffer();
|
||||
m_eyes[eye].clear({ 1, 0, 0, 1 });
|
||||
m_eyes[eye].unbindFramebuffer();
|
||||
}
|
||||
|
||||
int attempts = 50;
|
||||
do
|
||||
{
|
||||
int nc = 0;
|
||||
for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
|
||||
{
|
||||
if (hmd->GetTrackedDeviceClass(nDevice) == vr::TrackedDeviceClass_HMD)
|
||||
{
|
||||
dev_tracksys = ReadPropString(nDevice, vr::Prop_TrackingSystemName_String);
|
||||
dev_serial = ReadPropString(nDevice, vr::Prop_SerialNumber_String);
|
||||
dev_model = ReadPropString(nDevice, vr::Prop_ModelNumber_String);
|
||||
dev_manufacturer = ReadPropString(nDevice, vr::Prop_ManufacturerName_String);
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
attempts--;
|
||||
} while (attempts > 0 && dev_serial.empty());
|
||||
|
||||
vr::CVRSettingHelper s(settings);
|
||||
vr::CVRSettingHelper s(m_settings);
|
||||
float timeout = s.GetFloat(vr::k_pch_Power_Section, vr::k_pch_Power_TurnOffScreensTimeout_Float);
|
||||
s.SetFloat(vr::k_pch_Power_Section, vr::k_pch_Power_TurnOffScreensTimeout_Float, 0.5);
|
||||
|
||||
@@ -69,194 +36,92 @@ void Vive::Terminate()
|
||||
vr::VR_Shutdown();
|
||||
}
|
||||
|
||||
void Vive::ResetYaw()
|
||||
{
|
||||
yaw_offset = euler.y;
|
||||
}
|
||||
|
||||
void Vive::Update()
|
||||
{
|
||||
if (!(hmd && comp))
|
||||
if (!(m_hmd && m_comp))
|
||||
return;
|
||||
|
||||
vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
|
||||
comp->WaitGetPoses(poses, vr::k_unMaxTrackedDeviceCount, NULL, 0);
|
||||
auto& hmdPose = poses[vr::k_unTrackedDeviceIndex_Hmd];
|
||||
m_comp->WaitGetPoses(poses, vr::k_unMaxTrackedDeviceCount, NULL, 0);
|
||||
auto& current_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
|
||||
|
||||
for (int eye = 0; eye < 2; ++eye)
|
||||
{
|
||||
|
||||
// Get view and projection matrices
|
||||
vr::HmdMatrix44_t p = hmd->GetProjectionMatrix((vr::EVREye)eye, 0.2f, 1000.f);
|
||||
float eyeProj[4][4] = {
|
||||
vr::HmdMatrix44_t p = m_hmd->GetProjectionMatrix((vr::EVREye)eye, 0.2f, 1000.f);
|
||||
float data_eye_proj[16] = {
|
||||
p.m[0][0], p.m[1][0], p.m[2][0], p.m[3][0],
|
||||
p.m[0][1], p.m[1][1], p.m[2][1], p.m[3][1],
|
||||
p.m[0][2], p.m[1][2], p.m[2][2], p.m[3][2],
|
||||
p.m[0][3], p.m[1][3], p.m[2][3], p.m[3][3],
|
||||
};
|
||||
|
||||
vr::HmdMatrix34_t e = hmd->GetEyeToHeadTransform((vr::EVREye)eye);
|
||||
float eyePose[4][4] = {
|
||||
vr::HmdMatrix34_t e = m_hmd->GetEyeToHeadTransform((vr::EVREye)eye);
|
||||
float data_eye_pose[16] = {
|
||||
e.m[0][0], e.m[1][0], e.m[2][0], 0,
|
||||
e.m[0][1], e.m[1][1], e.m[2][1], 0,
|
||||
e.m[0][2], e.m[1][2], e.m[2][2], 0,
|
||||
e.m[0][3], e.m[1][3], e.m[2][3], 1,
|
||||
};
|
||||
|
||||
vr::HmdMatrix34_t h = hmdPose.mDeviceToAbsoluteTracking;
|
||||
float hmdPose[4][4] = {
|
||||
vr::HmdMatrix34_t h = current_pose.mDeviceToAbsoluteTracking;
|
||||
float data_hmd_pose[16] = {
|
||||
h.m[0][0], h.m[1][0], h.m[2][0], 0,
|
||||
h.m[0][1], h.m[1][1], h.m[2][1], 0,
|
||||
h.m[0][2], h.m[1][2], h.m[2][2], 0,
|
||||
0, 0, 0, 1,
|
||||
0, 0, 0, 1, // rotation only
|
||||
//h.m[0][3], h.m[1][3], h.m[2][3], 1,
|
||||
};
|
||||
|
||||
auto mat_proj = glm::make_mat4((float*)eyeProj);
|
||||
auto mat_pose = glm::inverse(glm::make_mat4((float*)hmdPose));
|
||||
auto mat_eye = glm::inverse(glm::make_mat4((float*)eyePose));
|
||||
auto hmd_position = glm::vec3(h.m[0][3], h.m[1][3], h.m[2][3]);
|
||||
auto mat_proj = glm::make_mat4(data_eye_proj);
|
||||
auto mat_pose = glm::inverse(glm::make_mat4(data_hmd_pose));
|
||||
auto mat_eye = glm::inverse(glm::make_mat4(data_eye_pose));
|
||||
|
||||
proj[eye] = mat_proj;
|
||||
view[eye] = mat_eye * mat_pose;
|
||||
pose = mat_pose;
|
||||
m_proj[eye] = mat_proj;
|
||||
m_view[eye] = mat_eye * mat_pose;
|
||||
m_pose = mat_pose;
|
||||
|
||||
for (auto& c : controllers)
|
||||
c.valid = false;
|
||||
for (auto& c : trackers)
|
||||
c.valid = false;
|
||||
|
||||
int nc = 0;
|
||||
int nt = 0;
|
||||
for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
|
||||
for (int id = 0; id < vr::k_unMaxTrackedDeviceCount; id++)
|
||||
{
|
||||
if (poses[nDevice].bPoseIsValid)
|
||||
switch (m_hmd->GetTrackedDeviceClass(id))
|
||||
{
|
||||
vr::HmdMatrix34_t p = poses[nDevice].mDeviceToAbsoluteTracking;
|
||||
float mat[4][4] = {
|
||||
p.m[0][0], p.m[1][0], p.m[2][0], 0,
|
||||
p.m[0][1], p.m[1][1], p.m[2][1], 0,
|
||||
p.m[0][2], p.m[1][2], p.m[2][2], 0,
|
||||
p.m[0][3], p.m[1][3], p.m[2][3], 1,
|
||||
};
|
||||
switch (hmd->GetTrackedDeviceClass(nDevice))
|
||||
{
|
||||
case vr::TrackedDeviceClass_Controller:
|
||||
{
|
||||
vr::EVRInitError error;
|
||||
vr::ETrackedControllerRole controllerRole = (vr::ETrackedControllerRole)
|
||||
hmd->GetInt32TrackedDeviceProperty(nDevice, vr::ETrackedDeviceProperty::Prop_ControllerRoleHint_Int32);
|
||||
|
||||
auto& c = controllers[nc];
|
||||
c.index = nc;
|
||||
c.active = true;
|
||||
c.valid = true;
|
||||
hmd->GetControllerState(nDevice, &c.state, sizeof(vr::VRControllerState_t));
|
||||
auto c_mat = glm::translate(-hmd_position) * glm::make_mat4((float*)mat);
|
||||
c.update(c_mat);
|
||||
c.buttons_bits = c.state.ulButtonPressed;
|
||||
c.role = controllerRole;
|
||||
for (int axi = 0; axi < 5; axi++)
|
||||
{
|
||||
c.axis[axi].x = c.state.rAxis[axi].x;
|
||||
c.axis[axi].y = c.state.rAxis[axi].y;
|
||||
|
||||
for (auto b : { Controller::ButtonAxis::Trigger })
|
||||
{
|
||||
if (axi != (uint8_t)b)
|
||||
continue;
|
||||
if (glm::compMax(glm::abs(c.axis[axi])) > 0.f && !c.buttons_axis[(uint8_t)b])
|
||||
{
|
||||
c.buttons_axis[(uint8_t)b] = true;
|
||||
if (on_button_axis)
|
||||
on_button_axis(c, b, Controller::Action::Press);
|
||||
}
|
||||
if (glm::compMax(glm::abs(c.axis[axi])) == 0.f && c.buttons_axis[(uint64_t)b])
|
||||
{
|
||||
c.buttons_axis[(uint8_t)b] = false;
|
||||
if (on_button_axis)
|
||||
on_button_axis(c, b, Controller::Action::Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto btn = c.state.ulButtonPressed;
|
||||
for (auto b : { Controller::Button::Trigger, Controller::Button::Grip })
|
||||
{
|
||||
if ((btn & (uint64_t)b) != 0 && !c.buttons[(uint64_t)b])
|
||||
{
|
||||
c.buttons[(uint64_t)b] = true;
|
||||
if (on_button)
|
||||
on_button(c, b, Controller::Action::Press);
|
||||
}
|
||||
if ((btn & (uint64_t)b) == 0 && c.buttons[(uint64_t)b])
|
||||
{
|
||||
c.buttons[(uint64_t)b] = false;
|
||||
if (on_button)
|
||||
on_button(c, b, Controller::Action::Release);
|
||||
}
|
||||
}
|
||||
nc++;
|
||||
}
|
||||
break;
|
||||
case vr::TrackedDeviceClass_HMD:
|
||||
{
|
||||
auto level = hmd->GetTrackedDeviceActivityLevel(nDevice);
|
||||
active = (level == vr::k_EDeviceActivityLevel_UserInteraction);
|
||||
}
|
||||
break;
|
||||
case vr::TrackedDeviceClass_Invalid:
|
||||
break;
|
||||
case vr::TrackedDeviceClass_GenericTracker:
|
||||
{
|
||||
auto& c = trackers[nt];
|
||||
c.index = nt;
|
||||
c.active = true;
|
||||
c.valid = true;
|
||||
c.update(glm::make_mat4((float*)mat));
|
||||
}
|
||||
break;
|
||||
case vr::TrackedDeviceClass_TrackingReference:
|
||||
m_active = (m_hmd->GetTrackedDeviceActivityLevel(id) == vr::k_EDeviceActivityLevel_UserInteraction);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nc > 1 && swap_controllers)
|
||||
{
|
||||
std::swap(controllers[0], controllers[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Vive::Draw()
|
||||
{
|
||||
if (!(hmd && comp && comp_attempts < 10))
|
||||
if (!Valid())
|
||||
return;
|
||||
|
||||
for (int eye = 0; eye < 2; ++eye)
|
||||
{
|
||||
eyes[eye].bindFramebuffer();
|
||||
eyes[eye].clear(background);
|
||||
glViewport(0, 0, eyes[eye].getWidth(), eyes[eye].getHeight());
|
||||
m_eyes[eye].bindFramebuffer();
|
||||
m_eyes[eye].clear();
|
||||
glViewport(0, 0, m_eyes[eye].getWidth(), m_eyes[eye].getHeight());
|
||||
|
||||
if (on_draw)
|
||||
on_draw(proj[eye], view[eye], pose);
|
||||
on_draw(m_proj[eye], m_view[eye], m_pose);
|
||||
|
||||
eyes[eye].unbindFramebuffer();
|
||||
m_eyes[eye].unbindFramebuffer();
|
||||
}
|
||||
|
||||
vr::Texture_t eyeTexture0 = { (void*)eyes[0].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||
if (auto err = comp->Submit(vr::EVREye::Eye_Left, &eyeTexture0) != vr::EVRCompositorError::VRCompositorError_None)
|
||||
vr::Texture_t eyeTexture0 = { (void*)m_eyes[0].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||
if (auto err = m_comp->Submit(vr::EVREye::Eye_Left, &eyeTexture0) != vr::EVRCompositorError::VRCompositorError_None)
|
||||
{
|
||||
LOG("Compositor error %d", err);
|
||||
comp_attempts++;
|
||||
return;
|
||||
}
|
||||
vr::Texture_t eyeTexture1 = { (void*)eyes[1].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||
if (auto err = comp->Submit(vr::EVREye::Eye_Right, &eyeTexture1) != vr::EVRCompositorError::VRCompositorError_None)
|
||||
vr::Texture_t eyeTexture1 = { (void*)m_eyes[1].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||
if (auto err = m_comp->Submit(vr::EVREye::Eye_Right, &eyeTexture1) != vr::EVRCompositorError::VRCompositorError_None)
|
||||
{
|
||||
LOG("Compositor error %d", err);
|
||||
comp_attempts++;
|
||||
@@ -265,11 +130,9 @@ void Vive::Draw()
|
||||
comp_attempts = 0;
|
||||
|
||||
glFlush();
|
||||
// glFinish();
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
bool Vive::Valid()
|
||||
{
|
||||
return comp && comp_attempts < 10;
|
||||
return m_hmd && m_comp && comp_attempts < 10;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user