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);