diff --git a/android/quest/src/main/AndroidManifest.xml b/android/quest/src/main/AndroidManifest.xml
index 7f57ae9..9f1033e 100644
--- a/android/quest/src/main/AndroidManifest.xml
+++ b/android/quest/src/main/AndroidManifest.xml
@@ -9,8 +9,8 @@
-
-
+
+
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/android/quest/src/main/cpp/oculus_vr.cpp b/android/quest/src/main/cpp/oculus_vr.cpp
index 1456f7f..3e1df7c 100644
--- a/android/quest/src/main/cpp/oculus_vr.cpp
+++ b/android/quest/src/main/cpp/oculus_vr.cpp
@@ -22,7 +22,7 @@ struct QuestController : public VRController
void update_state(double predictedDisplayTime, glm::vec3 head_pos)
{
vrapi_GetInputTrackingState(ovr_context, id, predictedDisplayTime, &tracking);
- glm::vec3 c_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position) - head_pos;
+ glm::vec3 c_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position);
auto c_rot_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation);
auto c_rot_ovr_tp = ovrMatrix4f_Transpose(&c_rot_ovr);
glm::mat4 c_rot = glm::make_mat4((float*)&c_rot_ovr_tp);
diff --git a/src/app.cpp b/src/app.cpp
index 1f50845..a3fd76d 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -624,7 +624,7 @@ void App::update(float dt)
auto observer = std::bind(&App::update_ui_observer, this, std::placeholders::_1);
- if (vr_active)
+ if (vr_active && ui_visible)
{
uirtt.bindFramebuffer();
uirtt.clear();
diff --git a/src/app_events.cpp b/src/app_events.cpp
index 993071f..32b87e3 100644
--- a/src/app_events.cpp
+++ b/src/app_events.cpp
@@ -31,7 +31,7 @@ void App::tick(float dt)
void App::resize(float w, float h)
{
LOG("App::resize %d %d", (int)w, (int)h);
- uirtt.create(w, h);
+ uirtt.create(w, h, -1, GL_RGBA8, true);
redraw = true;
width = w;
height = h;
diff --git a/src/app_vr.cpp b/src/app_vr.cpp
index ac75bd6..2cbbf0a 100644
--- a/src/app_vr.cpp
+++ b/src/app_vr.cpp
@@ -6,6 +6,7 @@
#ifdef _WIN32
bool win32_vr_start();
void win32_vr_stop();
+void win32_render_thread_notify();
#endif
bool trigger_down = false;
@@ -16,6 +17,7 @@ glm::vec2 controller_cursor;
bool ui_inside = false;
bool ui_capture = false;
Sphere controller_ray;
+glm::mat4 head_pose;
bool App::vr_start()
{
@@ -52,42 +54,57 @@ void App::vr_draw_ui()
void App::vr_update(float dt)
{
- glm::vec3 hit;
- float t;
- glm::mat3 m = glm::transpose(Canvas::I->m_cam_rot);
- auto o = m * glm::vec3(0, 0, -1);
- auto r = m * glm::vec3(1, 0, 0);
- auto n = m * glm::vec3(0, 0, 1);
- auto u = m * glm::vec3(0, 1, 0);
+ canvas->m_canvas->m_cam_fov = 45;
+ float tan_fov = glm::tan(glm::radians(canvas->m_canvas->m_cam_fov / 2.f));
+ glm::vec3 aspect = { (float)uirtt.getWidth() / (float)uirtt.getHeight(), 1.f, 1.f };
+ glm::mat4 m = (
+ glm::scale(glm::vec3(100)) *
+ glm::transpose(canvas->m_canvas->m_cam_rot) *
+ glm::translate(glm::vec3(0, 0, -1)) *
+ glm::scale(aspect * tan_fov)
+ );
+ glm::mat4 mm = glm::inverse(m);
+ auto o = glm::vec3(m * glm::vec4(0, 0, 0, 1));
+ auto r = glm::normalize(glm::vec3(glm::vec4(1, 0, 0, 0) * mm));
+ auto n = glm::normalize(glm::vec3(glm::vec4(0, 0, 1, 0) * mm));
+ auto u = glm::normalize(glm::vec3(glm::vec4(0, 1, 0, 0) * mm));
auto co = vr_controllers[0].get_pos();
auto cd = co + glm::mat3(vr_controllers[0].m_mat) * glm::vec3(0, 0, -1);
ui_inside = false;
+ glm::vec3 hit;
+ float t;
if (ray_intersect(co, cd, o, n, r, hit, t))
{
- glm::mat4 plane_camera = glm::lookAt(o, n, u);
- glm::vec4 plane_local = (plane_camera * glm::vec4(hit, 1)) * 2.f;
+ glm::mat4 plane_camera = m;
+ glm::vec4 plane_local = (mm * glm::vec4(hit, 1));
if (glm::all(glm::lessThanEqual(glm::abs(xy(plane_local)), glm::vec2(1.0f))))
{
- controller_cursor.x = -(plane_local.x * 0.5f - 0.5f) * width;
- controller_cursor.y = height - (plane_local.y * 0.5f + 0.5f) * height - 1;
+ controller_cursor.x = -(-plane_local.x * 0.5f - 0.5f) * width;
+ controller_cursor.y = (-plane_local.y * 0.5f + 0.5f) * height;
if (!down_controller && ui_visible)
{
async_start();
mouse_move(controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
async_end();
ui_inside = true;
+#ifdef _WIN32
+ win32_render_thread_notify();
+#endif
}
}
}
if (down_controller)
{
- controller_points.add(down_controller->get_pos_n() * 800.f);
+ glm::vec3 head_position = head_pose[3];
+ glm::vec3 c_pos = glm::normalize(down_controller->get_pos() - head_position) * 800.f;
+ controller_points.add(c_pos);
auto p = controller_points.average();
- if (glm::distance(p, controller_last_point) > 10)
+ if (glm::distance(p, controller_last_point) > 1)
{
async_start();
Canvas::I->stroke_update(p, down_controller->get_trigger_value());
+ Canvas::I->stroke_draw();
async_end();
controller_last_point = p;
redraw = true;
@@ -106,11 +123,17 @@ void App::vr_analog(const VRController& c, VRController::kButton b, VRController
{
mouse_down(0, controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
ui_capture = true;
+#ifdef _WIN32
+ win32_render_thread_notify();
+#endif
}
else
{
mouse_up(0, controller_cursor.x, controller_cursor.y, kEventSource::Mouse, false);
ui_capture = false;
+#ifdef _WIN32
+ win32_render_thread_notify();
+#endif
}
async_end();
}
@@ -118,11 +141,12 @@ void App::vr_analog(const VRController& c, VRController::kButton b, VRController
{
if (a == VRController::kAction::Press)
{
- glm::vec3 pos = c.get_pos_n() * 800.f;
+ glm::vec3 head_position = head_pose[3];
+ glm::vec3 c_pos = glm::normalize(c.get_pos() - head_position) * 800.f;
async_start();
- Canvas::I->stroke_start(pos, force.x);
+ Canvas::I->stroke_start(c_pos, force.x);
async_end();
- controller_last_point = pos;
+ controller_last_point = c_pos;
controller_points.clear();
down_controller = &c;
}
@@ -179,7 +203,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
for (int plane_index = 0; plane_index < 6; plane_index++)
{
auto plane_mvp = proj * camera *
- glm::scale(glm::vec3(canvas->m_canvas->m_order.size() + 500)) *
+ glm::scale(glm::vec3(canvas->m_canvas->m_order.size() * 20)) *
canvas->m_canvas->m_plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1));
@@ -206,7 +230,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
int z = (int)(canvas->m_canvas->m_order.size() - i);
auto plane_mvp_z = proj * camera *
- glm::scale(glm::vec3(z + 1) * 100.f) *
+ glm::scale(glm::vec3(z) * 20.f) *
//glm::eulerAngleYXZ(yaw, pitch, roll) *
canvas->m_canvas->m_plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1));
@@ -310,7 +334,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
}
}
- float tan_fov = glm::tan(glm::radians(canvas->m_canvas->m_cam_fov / 2.f)) * 0.5f;
+ App::I.grid->draw_heightmap(proj, camera, false);
+
+ float tan_fov = glm::tan(glm::radians(canvas->m_canvas->m_cam_fov / 2.f));
glm::vec3 aspect = { (float)uirtt.getWidth() / (float)uirtt.getHeight(), 1.f, 1.f };
// draw the frame
@@ -397,16 +423,17 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
m_face_plane.draw_fill();
}
-/*
+
// draw the motion controller sphere
+ if (ui_visible && ui_inside)
{
- auto mvp = proj * camera * glm::translate(glm::normalize(vr_controller_pos));
+ auto mvp = proj * camera * vr_controllers[0].m_mat;
ShaderManager::use(kShader::Color);
- ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 });
- ShaderManager::u_mat4(kShaderUniform::MVP, mvp * glm::scale(glm::vec3(.025)));
+ ShaderManager::u_vec4(kShaderUniform::Col, { 1, 0, 1, 1 });
+ ShaderManager::u_mat4(kShaderUniform::MVP, mvp * glm::scale(glm::vec3(.0125, .0125, .07)));
sphere.draw_fill();
}
-*/
+
// draw the motion controller brush
if (!ui_visible || !ui_inside)
diff --git a/src/canvas.h b/src/canvas.h
index 3997d43..6a335c8 100644
--- a/src/canvas.h
+++ b/src/canvas.h
@@ -10,11 +10,16 @@
#define CANVAS_RES 1536
+class LayerFrame
+{
+
+};
+
class Layer
{
public:
- //Layer() = default;
- //Layer(const Layer&) = delete;
+ Layer() = default;
+ Layer(const Layer&) = delete;
RTT m_rtt[6];
glm::vec4 m_dirty_box[6] = SIXPLETTE(glm::vec4(0));
bool m_dirty_face[6] = SIXPLETTE(false);
diff --git a/src/hmd.cpp b/src/hmd.cpp
index 0faa19e..f919339 100644
--- a/src/hmd.cpp
+++ b/src/hmd.cpp
@@ -87,17 +87,22 @@ void Vive::Update()
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, // rotation only
- //h.m[0][3], h.m[1][3], h.m[2][3], 1,
+ // 0, 0, 0, 1, // rotation only
+ h.m[0][3], h.m[1][3], h.m[2][3], 1,
};
+ if (!m_position_valid)
+ {
+ m_initial_position = { h.m[0][3], h.m[1][3], h.m[2][3] };
+ m_position_valid = true;
+ }
+
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));
- glm::vec3 head_position(h.m[0][3], h.m[1][3], h.m[2][3]);
m_proj[eye] = mat_proj;
- m_view[eye] = mat_eye * mat_pose;
+ m_view[eye] = mat_eye * mat_pose * glm::translate(m_initial_position);
m_pose = glm::make_mat4(data_hmd_pose);
// invalidate controller state
@@ -120,7 +125,7 @@ void Vive::Update()
{
m_controllers[controller_index].m_valid = true;
m_hmd->GetControllerState(id, &m_controllers[controller_index].m_state, sizeof(vr::VRControllerState_t));
- m_controllers[controller_index].m_mat = glm::translate(-head_position) * Pose2Mat(poses[id].mDeviceToAbsoluteTracking);
+ m_controllers[controller_index].m_mat = glm::translate(-m_initial_position) * Pose2Mat(poses[id].mDeviceToAbsoluteTracking);
auto pressed_mask = m_controllers[controller_index].m_state.ulButtonPressed;
for (uint8_t bi = 0; bi < (uint8_t)ViveController::kButton::COUNT; bi++)
diff --git a/src/hmd.h b/src/hmd.h
index 2c91f0d..848bb0f 100644
--- a/src/hmd.h
+++ b/src/hmd.h
@@ -40,6 +40,8 @@ struct Vive
glm::mat4 m_view[2];
glm::mat4 m_proj[2];
glm::mat4 m_pose;
+ glm::vec3 m_initial_position;
+ bool m_position_valid = false;
bool m_active = false;
std::function on_draw = nullptr;
std::function on_button = nullptr;
diff --git a/src/main.cpp b/src/main.cpp
index 9767581..65deba0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -164,6 +164,11 @@ void async_unlock()
}
}
+void win32_render_thread_notify()
+{
+ render_cv.notify_all();
+}
+
void win32_show_cursor(bool visible)
{
std::lock_guard lock(main_task_mutex);
@@ -551,8 +556,8 @@ bool win32_vr_start()
const int framerate = (1.f / target_tick_rate) * 1000;
const int diff = framerate - (t1 - t0);
- t0 = t1;
hmd_render_cv.wait_for(lock, std::chrono::milliseconds(diff));
+ t0 = t1;
}
App::I.vr_active = false;
App::I.has_vr = false;
@@ -817,9 +822,9 @@ int main(int argc, char** argv)
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
- WGL_STENCIL_BITS_ARB, 8,
- WGL_SAMPLE_BUFFERS_ARB, 1, // Number of buffers (must be 1 at time of writing)
- WGL_SAMPLES_ARB, 4, // Number of samples
+ //WGL_STENCIL_BITS_ARB, 8,
+ //WGL_SAMPLE_BUFFERS_ARB, 1, // Number of buffers (must be 1 at time of writing)
+ //WGL_SAMPLES_ARB, 4, // Number of samples
0
};
UINT numFormat;
@@ -844,6 +849,8 @@ int main(int argc, char** argv)
return -1; // A negative number because you are a negative one
}
+ //wglSwapIntervalEXT(1);
+
bool start_in_vr = false;
if (argc > 1)
{
@@ -894,7 +901,7 @@ int main(int argc, char** argv)
BT_SetTerminate();
LOG("start render thread");
const float target_fps = 10;
- const float target_tick_rate = 60;
+ const float target_tick_rate = 10;
unsigned long t0 = GetTickCount64();
unsigned long t1;
bool first_frame = true;
@@ -912,7 +919,6 @@ int main(int argc, char** argv)
timer_stylus += dt;
timer_ink_touch += dt;
timer_ink_pen += dt;
- t0 = t1;
if (one_sec > 1.f)
{
@@ -993,20 +999,20 @@ int main(int argc, char** argv)
if (App::I.redraw)
{
async_lock();
- App::I.redraw = true;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
App::I.clear();
App::I.update(frame_timer);
SwapBuffers(hDC);
async_unlock();
frame_timer = 0;
- //LOG("swap main");
frames++;
}
const int framerate = (1.f / target_tick_rate) * 1000;
const int diff = framerate - (t1 - t0);
render_cv.wait_for(lock, std::chrono::milliseconds(diff));
+ //std::this_thread::sleep_for(std::chrono::milliseconds(30));
+ t0 = t1;
}
LOG("renderer terminated");
});
diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp
index 25c9e5b..3db15b5 100644
--- a/src/node_panel_grid.cpp
+++ b/src/node_panel_grid.cpp
@@ -224,8 +224,10 @@ void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camer
auto nav = m_hm_image.m_data ? -(m_hm_preview_nav->m_value - 0.5f) : glm::vec2(0);
auto mvp = proj * camera
+ * glm::scale(glm::vec3(100))
* glm::translate(glm::vec3(0, get_offset(), 0))
- * glm::translate(glm::vec3(nav.x, get_offset(), nav.y));
+ * glm::translate(glm::vec3(nav.x, get_offset(), nav.y))
+ ;
auto light_yaw = m_hm_lyaw->get_value() * glm::pi() * 2.f;
auto light_pitch = m_hm_lpitch->get_value() * 5;
@@ -303,9 +305,11 @@ void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camer
glGetIntegerv(GL_VIEWPORT, vp);
auto aspect_ratio = (float)vp[3] / (float)vp[2];
glEnable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
ShaderManager::use(kShader::Texture);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1.f, 1.f, -1.f, 1.f) *
+ glm::scale(glm::vec3(100)) *
glm::translate(glm::vec3(p2d, 0)) * glm::scale(glm::vec3(.1f * aspect_ratio, .1f, 1.f)));
glActiveTexture(GL_TEXTURE0);
m_sampler_linear.bind(0);