implement motion controllers and vr drawing with brush preview

This commit is contained in:
2018-11-02 13:49:15 +01:00
parent 3b73e84fe9
commit 3ee10bb88d
13 changed files with 202 additions and 46 deletions

View File

@@ -9,6 +9,14 @@ Vive::Vive()
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;
@@ -18,6 +26,8 @@ bool Vive::Initialize()
comp = vr::VRCompositor();
if (!comp)
return false;
settings = vr::VRSettings();
hmd->GetRecommendedRenderTargetSize(&eyeWidth, &eyeHeight);
LOG("Eye target resolution: %dx%d\n", eyeWidth, eyeHeight);
@@ -37,22 +47,20 @@ bool Vive::Initialize()
{
if (hmd->GetTrackedDeviceClass(nDevice) == vr::TrackedDeviceClass_HMD)
{
auto read_string = [nDevice, this](vr::ETrackedDeviceProperty p) -> std::string {
size_t len = hmd->GetStringTrackedDeviceProperty(nDevice, p, nullptr, 0);
std::string str(len, '\0');
hmd->GetStringTrackedDeviceProperty(nDevice, p, (char*)str.data(), len);
return str;
};
dev_tracksys = read_string(vr::Prop_TrackingSystemName_String);
dev_serial = read_string(vr::Prop_SerialNumber_String);
dev_model = read_string(vr::Prop_ModelNumber_String);
dev_manufacturer = read_string(vr::Prop_ManufacturerName_String);
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);
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);
return true;
}
@@ -66,9 +74,9 @@ void Vive::ResetYaw()
yaw_offset = euler.y;
}
void Vive::Draw()
void Vive::Update()
{
if (!(hmd && comp && comp_attempts < 10))
if (!(hmd && comp))
return;
vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
@@ -77,9 +85,6 @@ void Vive::Draw()
for (int eye = 0; eye < 2; ++eye)
{
eyes[eye].bindFramebuffer();
eyes[eye].clear(background);
glViewport(0, 0, eyes[eye].getWidth(), eyes[eye].getHeight());
// Get view and projection matrices
vr::HmdMatrix44_t p = hmd->GetProjectionMatrix((vr::EVREye)eye, 0.2f, 1000.f);
@@ -110,10 +115,11 @@ void Vive::Draw()
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]);
proj[eye] = mat_proj;
view[eye] = mat_eye * mat_pose;
pose = glm::make_mat4((float*)hmdPose);
pose = mat_pose;
for (auto& c : controllers)
c.valid = false;
@@ -146,13 +152,32 @@ void Vive::Draw()
c.active = true;
c.valid = true;
hmd->GetControllerState(nDevice, &c.state, sizeof(vr::VRControllerState_t));
c.update(glm::make_mat4((float*)mat));
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;
@@ -175,7 +200,11 @@ void Vive::Draw()
}
break;
case vr::TrackedDeviceClass_HMD:
break;
{
auto level = hmd->GetTrackedDeviceActivityLevel(nDevice);
active = (level == vr::k_EDeviceActivityLevel_UserInteraction);
}
break;
case vr::TrackedDeviceClass_Invalid:
break;
case vr::TrackedDeviceClass_GenericTracker:
@@ -199,12 +228,26 @@ void Vive::Draw()
{
std::swap(controllers[0], controllers[1]);
}
}
}
void Vive::Draw()
{
if (!(hmd && comp && comp_attempts < 10))
return;
for (int eye = 0; eye < 2; ++eye)
{
eyes[eye].bindFramebuffer();
eyes[eye].clear(background);
glViewport(0, 0, eyes[eye].getWidth(), eyes[eye].getHeight());
if (on_draw)
on_draw(proj[eye], view[eye], mat_pose);
on_draw(proj[eye], view[eye], pose);
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)
{