cleanup
This commit is contained in:
15
src/bezier.h
15
src/bezier.h
@@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// link: https://www.codeproject.com/Articles/25237/Bezier-Curves-Made-Simple
|
||||||
|
|
||||||
class BezierCurve
|
class BezierCurve
|
||||||
{
|
{
|
||||||
static double FactorialLookup[33];
|
static double FactorialLookup[33];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// just check if n is appropriate, then return the result
|
// just check if n is appropriate, then return the result
|
||||||
static double factorial(int n)
|
static double factorial(int n)
|
||||||
{
|
{
|
||||||
// if (n < 0) { throw new Exception("n is less than 0"); }
|
return FactorialLookup[n];
|
||||||
// if (n > 32) { throw new Exception("n is greater than 32"); }
|
|
||||||
return FactorialLookup[n]; /* returns the value n! as a SUMORealing point number */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double Ni(int n, int i)
|
static double Ni(int n, int i)
|
||||||
@@ -27,10 +27,8 @@ public:
|
|||||||
static double Bernstein(int n, int i, double t)
|
static double Bernstein(int n, int i, double t)
|
||||||
{
|
{
|
||||||
double basis;
|
double basis;
|
||||||
double ti; /* t^i */
|
double ti;
|
||||||
double tni; /* (1 - t)^i */
|
double tni;
|
||||||
|
|
||||||
/* Prevent problems with pow */
|
|
||||||
|
|
||||||
if (t == 0.0 && i == 0)
|
if (t == 0.0 && i == 0)
|
||||||
ti = 1.0;
|
ti = 1.0;
|
||||||
@@ -49,9 +47,6 @@ public:
|
|||||||
|
|
||||||
static glm::vec2 Bezier2D(const std::vector<glm::vec2>& b, double t)
|
static glm::vec2 Bezier2D(const std::vector<glm::vec2>& b, double t)
|
||||||
{
|
{
|
||||||
// if ((1.0 - t) < 5e-6)
|
|
||||||
// t = 1.0;
|
|
||||||
|
|
||||||
double px = 0.0;
|
double px = 0.0;
|
||||||
double py = 0.0;
|
double py = 0.0;
|
||||||
const int npts = (int)b.size();
|
const int npts = (int)b.size();
|
||||||
|
|||||||
@@ -424,8 +424,26 @@ void Canvas::stroke_draw()
|
|||||||
auto bb_sz = bb_max - bb_min;
|
auto bb_sz = bb_max - bb_min;
|
||||||
|
|
||||||
if (m_brush.m_tip_mix > 0.f)
|
if (m_brush.m_tip_mix > 0.f)
|
||||||
|
{
|
||||||
stroke_draw_mix(bb_min, bb_sz);
|
stroke_draw_mix(bb_min, bb_sz);
|
||||||
|
|
||||||
|
glViewport(0, 0, m_width, m_height);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
tex.bind();
|
||||||
|
m_sampler_brush.bind(0);
|
||||||
|
m_sampler_bg.bind(1);
|
||||||
|
m_sampler_stencil.bind(2);
|
||||||
|
m_sampler.bind(3);
|
||||||
|
//m_sampler_linear.bind(5);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
stencil.bind();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
m_mixer.bindTexture();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
// check if plane is even visible
|
// check if plane is even visible
|
||||||
@@ -529,7 +547,7 @@ void Canvas::stroke_draw()
|
|||||||
glm::max(zw(m_dirty_box[i]), (glm::vec2)(tex_pos + tex_sz))
|
glm::max(zw(m_dirty_box[i]), (glm::vec2)(tex_pos + tex_sz))
|
||||||
);
|
);
|
||||||
|
|
||||||
//ShaderManager::use(kShader::Stroke);
|
ShaderManager::use(kShader::Stroke);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj);
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj);
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush.m_tip_color.a));
|
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(s.col, m_brush.m_tip_color.a));
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
|
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
|
||||||
|
|||||||
217
src/hmd.cpp
217
src/hmd.cpp
@@ -3,61 +3,28 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <array>
|
#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()
|
bool Vive::Initialize()
|
||||||
{
|
{
|
||||||
vr::EVRInitError error;
|
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)
|
if (error != vr::EVRInitError::VRInitError_None)
|
||||||
return false;
|
return false;
|
||||||
comp = vr::VRCompositor();
|
|
||||||
if (!comp)
|
if (!(m_comp = vr::VRCompositor()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
settings = vr::VRSettings();
|
m_settings = vr::VRSettings();
|
||||||
|
|
||||||
hmd->GetRecommendedRenderTargetSize(&eyeWidth, &eyeHeight);
|
m_hmd->GetRecommendedRenderTargetSize(&m_eye_width, &m_eye_height);
|
||||||
LOG("Eye target resolution: %dx%d\n", eyeWidth, eyeHeight);
|
|
||||||
for (int eye = 0; eye < 2; ++eye)
|
for (int eye = 0; eye < 2; ++eye)
|
||||||
{
|
{
|
||||||
eyes[eye].create(eyeWidth, eyeHeight);
|
m_eyes[eye].create(m_eye_width, m_eye_height);
|
||||||
eyes[eye].bindFramebuffer();
|
m_eyes[eye].bindFramebuffer();
|
||||||
eyes[eye].clear({ 1, 0, 0, 1 });
|
m_eyes[eye].clear({ 1, 0, 0, 1 });
|
||||||
eyes[eye].unbindFramebuffer();
|
m_eyes[eye].unbindFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
int attempts = 50;
|
vr::CVRSettingHelper s(m_settings);
|
||||||
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);
|
|
||||||
float timeout = s.GetFloat(vr::k_pch_Power_Section, vr::k_pch_Power_TurnOffScreensTimeout_Float);
|
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);
|
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();
|
vr::VR_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vive::ResetYaw()
|
|
||||||
{
|
|
||||||
yaw_offset = euler.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vive::Update()
|
void Vive::Update()
|
||||||
{
|
{
|
||||||
if (!(hmd && comp))
|
if (!(m_hmd && m_comp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
|
||||||
comp->WaitGetPoses(poses, vr::k_unMaxTrackedDeviceCount, NULL, 0);
|
m_comp->WaitGetPoses(poses, vr::k_unMaxTrackedDeviceCount, NULL, 0);
|
||||||
auto& hmdPose = poses[vr::k_unTrackedDeviceIndex_Hmd];
|
auto& current_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
|
||||||
|
|
||||||
for (int eye = 0; eye < 2; ++eye)
|
for (int eye = 0; eye < 2; ++eye)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Get view and projection matrices
|
// Get view and projection matrices
|
||||||
vr::HmdMatrix44_t p = hmd->GetProjectionMatrix((vr::EVREye)eye, 0.2f, 1000.f);
|
vr::HmdMatrix44_t p = m_hmd->GetProjectionMatrix((vr::EVREye)eye, 0.2f, 1000.f);
|
||||||
float eyeProj[4][4] = {
|
float data_eye_proj[16] = {
|
||||||
p.m[0][0], p.m[1][0], p.m[2][0], p.m[3][0],
|
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][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][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],
|
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);
|
vr::HmdMatrix34_t e = m_hmd->GetEyeToHeadTransform((vr::EVREye)eye);
|
||||||
float eyePose[4][4] = {
|
float data_eye_pose[16] = {
|
||||||
e.m[0][0], e.m[1][0], e.m[2][0], 0,
|
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][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][2], e.m[1][2], e.m[2][2], 0,
|
||||||
e.m[0][3], e.m[1][3], e.m[2][3], 1,
|
e.m[0][3], e.m[1][3], e.m[2][3], 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
vr::HmdMatrix34_t h = hmdPose.mDeviceToAbsoluteTracking;
|
vr::HmdMatrix34_t h = current_pose.mDeviceToAbsoluteTracking;
|
||||||
float hmdPose[4][4] = {
|
float data_hmd_pose[16] = {
|
||||||
h.m[0][0], h.m[1][0], h.m[2][0], 0,
|
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][1], h.m[1][1], h.m[2][1], 0,
|
||||||
h.m[0][2], h.m[1][2], h.m[2][2], 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,
|
//h.m[0][3], h.m[1][3], h.m[2][3], 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto mat_proj = glm::make_mat4((float*)eyeProj);
|
auto mat_proj = glm::make_mat4(data_eye_proj);
|
||||||
auto mat_pose = glm::inverse(glm::make_mat4((float*)hmdPose));
|
auto mat_pose = glm::inverse(glm::make_mat4(data_hmd_pose));
|
||||||
auto mat_eye = glm::inverse(glm::make_mat4((float*)eyePose));
|
auto mat_eye = glm::inverse(glm::make_mat4(data_eye_pose));
|
||||||
auto hmd_position = glm::vec3(h.m[0][3], h.m[1][3], h.m[2][3]);
|
|
||||||
|
|
||||||
proj[eye] = mat_proj;
|
m_proj[eye] = mat_proj;
|
||||||
view[eye] = mat_eye * mat_pose;
|
m_view[eye] = mat_eye * mat_pose;
|
||||||
pose = mat_pose;
|
m_pose = mat_pose;
|
||||||
|
|
||||||
for (auto& c : controllers)
|
for (int id = 0; id < vr::k_unMaxTrackedDeviceCount; id++)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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:
|
case vr::TrackedDeviceClass_HMD:
|
||||||
{
|
m_active = (m_hmd->GetTrackedDeviceActivityLevel(id) == vr::k_EDeviceActivityLevel_UserInteraction);
|
||||||
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:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nc > 1 && swap_controllers)
|
|
||||||
{
|
|
||||||
std::swap(controllers[0], controllers[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vive::Draw()
|
void Vive::Draw()
|
||||||
{
|
{
|
||||||
if (!(hmd && comp && comp_attempts < 10))
|
if (!Valid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int eye = 0; eye < 2; ++eye)
|
for (int eye = 0; eye < 2; ++eye)
|
||||||
{
|
{
|
||||||
eyes[eye].bindFramebuffer();
|
m_eyes[eye].bindFramebuffer();
|
||||||
eyes[eye].clear(background);
|
m_eyes[eye].clear();
|
||||||
glViewport(0, 0, eyes[eye].getWidth(), eyes[eye].getHeight());
|
glViewport(0, 0, m_eyes[eye].getWidth(), m_eyes[eye].getHeight());
|
||||||
|
|
||||||
if (on_draw)
|
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 };
|
vr::Texture_t eyeTexture0 = { (void*)m_eyes[0].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||||
if (auto err = comp->Submit(vr::EVREye::Eye_Left, &eyeTexture0) != vr::EVRCompositorError::VRCompositorError_None)
|
if (auto err = m_comp->Submit(vr::EVREye::Eye_Left, &eyeTexture0) != vr::EVRCompositorError::VRCompositorError_None)
|
||||||
{
|
{
|
||||||
LOG("Compositor error %d", err);
|
LOG("Compositor error %d", err);
|
||||||
comp_attempts++;
|
comp_attempts++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vr::Texture_t eyeTexture1 = { (void*)eyes[1].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
vr::Texture_t eyeTexture1 = { (void*)m_eyes[1].getTextureID(), vr::ETextureType::TextureType_OpenGL, vr::ColorSpace_Linear };
|
||||||
if (auto err = comp->Submit(vr::EVREye::Eye_Right, &eyeTexture1) != vr::EVRCompositorError::VRCompositorError_None)
|
if (auto err = m_comp->Submit(vr::EVREye::Eye_Right, &eyeTexture1) != vr::EVRCompositorError::VRCompositorError_None)
|
||||||
{
|
{
|
||||||
LOG("Compositor error %d", err);
|
LOG("Compositor error %d", err);
|
||||||
comp_attempts++;
|
comp_attempts++;
|
||||||
@@ -265,11 +130,9 @@ void Vive::Draw()
|
|||||||
comp_attempts = 0;
|
comp_attempts = 0;
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
// glFinish();
|
|
||||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vive::Valid()
|
bool Vive::Valid()
|
||||||
{
|
{
|
||||||
return comp && comp_attempts < 10;
|
return m_hmd && m_comp && comp_attempts < 10;
|
||||||
}
|
}
|
||||||
|
|||||||
81
src/hmd.h
81
src/hmd.h
@@ -1,84 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "rtt.h"
|
#include "rtt.h"
|
||||||
|
|
||||||
struct Controller
|
|
||||||
{
|
|
||||||
enum class Button : uint64_t
|
|
||||||
{
|
|
||||||
Trigger = 0x200000000,
|
|
||||||
Pad = 0x100000000,
|
|
||||||
Menu = 0x000000002,
|
|
||||||
Grip = 0x000000004,
|
|
||||||
};
|
|
||||||
enum class ButtonAxis : uint8_t
|
|
||||||
{
|
|
||||||
Trigger = 1,
|
|
||||||
Pad = 0,
|
|
||||||
};
|
|
||||||
enum class Action
|
|
||||||
{
|
|
||||||
Press,
|
|
||||||
Release,
|
|
||||||
};
|
|
||||||
int index = 0;
|
|
||||||
bool active = false;
|
|
||||||
std::map<uint64_t, bool> buttons;
|
|
||||||
std::map<uint8_t, bool> buttons_axis;
|
|
||||||
uint64_t buttons_bits{ 0 };
|
|
||||||
glm::vec2 axis[5];
|
|
||||||
glm::mat4 xform{ 1 };
|
|
||||||
glm::vec3 pos{ 0 };
|
|
||||||
glm::vec3 rot{ 0 };
|
|
||||||
vr::VRControllerState_t state;
|
|
||||||
bool valid = false;
|
|
||||||
int role = 0;
|
|
||||||
|
|
||||||
void update(const glm::mat4& m)
|
|
||||||
{
|
|
||||||
xform = m;
|
|
||||||
pos = glm::vec3(m[3]);
|
|
||||||
//float sx = glm::length(glm::vec3(m[0]));
|
|
||||||
//float sy = glm::length(glm::vec3(m[1]));
|
|
||||||
//float sz = glm::length(glm::vec3(m[2]));
|
|
||||||
glm::extractEulerAngleXYZ(m, rot.x, rot.y, rot.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vive
|
struct Vive
|
||||||
{
|
{
|
||||||
int comp_attempts = 0;
|
int comp_attempts = 0;
|
||||||
uint32_t eyeWidth = 0, eyeHeight = 0;
|
uint32_t m_eye_width = 0, m_eye_height = 0;
|
||||||
RTT eyes[2];
|
RTT m_eyes[2];
|
||||||
vr::IVRSystem* hmd = nullptr;
|
vr::IVRSystem* m_hmd = nullptr;
|
||||||
vr::IVRCompositor* comp = nullptr;
|
vr::IVRCompositor* m_comp = nullptr;
|
||||||
vr::IVRSettings* settings = nullptr;
|
vr::IVRSettings* m_settings = nullptr;
|
||||||
glm::vec3 euler{ 0 };
|
glm::mat4 m_view[2];
|
||||||
glm::vec4 background{ .5, .2, .2, 1 };
|
glm::mat4 m_proj[2];
|
||||||
float yaw_offset = 0;
|
glm::mat4 m_pose;
|
||||||
glm::mat4 view[2];
|
bool m_active = false;
|
||||||
glm::mat4 proj[2];
|
std::function<void(const glm::mat4& m_proj, const glm::mat4& m_view, const glm::mat4& m_pose)> on_draw = nullptr;
|
||||||
glm::mat4 pose;
|
|
||||||
Controller controllers[32];
|
|
||||||
Controller trackers[32];
|
|
||||||
bool swap_controllers = false;
|
|
||||||
bool active = false;
|
|
||||||
std::string dev_serial{ "0000001" };
|
|
||||||
std::string dev_model{ "Vive" };
|
|
||||||
std::string dev_tracksys{ "lighthouse" };
|
|
||||||
std::string dev_manufacturer{ "HTC" };
|
|
||||||
std::function<void(const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose)> on_draw = nullptr;
|
|
||||||
std::function<void(const Controller&, Controller::Button, Controller::Action)> on_button = nullptr;
|
|
||||||
std::function<void(const Controller&, Controller::ButtonAxis, Controller::Action)> on_button_axis = nullptr;
|
|
||||||
|
|
||||||
Vive();
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void ResetYaw();
|
|
||||||
void Update();
|
void Update();
|
||||||
void Draw();
|
void Draw();
|
||||||
std::string ReadPropString(vr::TrackedDeviceIndex_t nDevice, vr::ETrackedDeviceProperty p);
|
|
||||||
bool Valid();
|
bool Valid();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
69
src/main.cpp
69
src/main.cpp
@@ -718,31 +718,6 @@ int main(int argc, char** argv)
|
|||||||
LOG("start hmd render thread");
|
LOG("start hmd render thread");
|
||||||
App::I.has_vr = true;
|
App::I.has_vr = true;
|
||||||
|
|
||||||
bool trigger_down = false;
|
|
||||||
cbuffer<glm::vec3, 10> controller_points;
|
|
||||||
glm::vec3 controller_last_point;
|
|
||||||
vive->on_button_axis = [&](const Controller& c, Controller::ButtonAxis b, Controller::Action a) {
|
|
||||||
if (b == Controller::ButtonAxis::Trigger)
|
|
||||||
{
|
|
||||||
if (a == Controller::Action::Press)
|
|
||||||
{
|
|
||||||
async_lock();
|
|
||||||
Canvas::I->stroke_start(vive->controllers[0].pos * 800.f, vive->controllers[0].axis[1].x, Canvas::I->m_current_brush);
|
|
||||||
async_unlock();
|
|
||||||
controller_last_point = vive->controllers[0].pos * 800.f;
|
|
||||||
controller_points.clear();
|
|
||||||
trigger_down = true;
|
|
||||||
}
|
|
||||||
if (a == Controller::Action::Release)
|
|
||||||
{
|
|
||||||
trigger_down = false;
|
|
||||||
async_lock();
|
|
||||||
Canvas::I->stroke_end();
|
|
||||||
async_unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const float target_tick_rate = 90;
|
const float target_tick_rate = 90;
|
||||||
unsigned long t0 = GetTickCount();
|
unsigned long t0 = GetTickCount();
|
||||||
while (running && vive->Valid())
|
while (running && vive->Valid())
|
||||||
@@ -752,25 +727,9 @@ int main(int argc, char** argv)
|
|||||||
float dt = (float)(t1 - t0) / 1000.0f;
|
float dt = (float)(t1 - t0) / 1000.0f;
|
||||||
|
|
||||||
vive->Update();
|
vive->Update();
|
||||||
App::I.vr_active = vive->active;
|
App::I.vr_active = vive->m_active;
|
||||||
App::I.vr_controller = vive->controllers[0].xform;
|
|
||||||
App::I.vr_controller_pos = vive->controllers[0].pos;
|
|
||||||
|
|
||||||
if (trigger_down)
|
if (vive->m_active)
|
||||||
{
|
|
||||||
controller_points.add(vive->controllers[0].pos * 800.f);
|
|
||||||
auto p = controller_points.average();
|
|
||||||
if (glm::distance(p, controller_last_point) > 1)
|
|
||||||
{
|
|
||||||
async_lock();
|
|
||||||
Canvas::I->stroke_update(p, vive->controllers[0].axis[1].x);
|
|
||||||
async_unlock();
|
|
||||||
controller_last_point = p;
|
|
||||||
App::I.redraw = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vive->active)
|
|
||||||
{
|
{
|
||||||
async_lock();
|
async_lock();
|
||||||
vive->Draw();
|
vive->Draw();
|
||||||
@@ -1135,29 +1094,23 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
return DefWindowProc(hWnd, msg, wp, lp);
|
return DefWindowProc(hWnd, msg, wp, lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||||
_In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
|
||||||
{
|
{
|
||||||
LPWSTR *szArgList{ nullptr };
|
LPWSTR *wargs = nullptr;
|
||||||
int argc{ 0 };
|
char** argv = nullptr;
|
||||||
char** argv{ nullptr };
|
int argc = 0;
|
||||||
|
|
||||||
szArgList = CommandLineToArgvW(GetCommandLine(), &argc);
|
|
||||||
if (szArgList == NULL)
|
|
||||||
{
|
|
||||||
MessageBox(NULL, L"Unable to parse command line", L"Error", MB_OK);
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// convert args from char to wchar
|
||||||
|
wargs = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||||
argv = new char*[argc + 1];
|
argv = new char*[argc + 1];
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
auto len = wcslen(szArgList[i]) + 1;
|
auto len = wcslen(wargs[i]) + 1;
|
||||||
argv[i] = new char[len];
|
argv[i] = new char[len];
|
||||||
wcstombs_s(nullptr, argv[i], len, szArgList[i], len);
|
wcstombs_s(nullptr, argv[i], len, wargs[i], len);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFree(szArgList);
|
LocalFree(wargs);
|
||||||
|
|
||||||
return main(argc, argv);
|
return main(argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user