#include "pch.h" #include "legacy_canvas_mode_helpers.h" #include "app.h" #include "canvas.h" #include "canvas_modes.h" #include "legacy_ui_overlay_services.h" #include "legacy_ui_gl_dispatch.h" #include "renderer_gl/opengl_capabilities.h" NodeCanvas* CanvasMode::node; namespace pp::legacy_canvas_mode { void set_canvas_mode_active_texture_unit(std::uint32_t unit_index) { pp::legacy::ui_gl::activate_texture_unit(unit_index, "CanvasMode"); } void apply_canvas_mode_capability(std::uint32_t state, bool enabled) { pp::legacy::ui_gl::set_capability(state, enabled, "CanvasMode"); } bool query_canvas_mode_capability(std::uint32_t state) { return pp::legacy::ui_gl::query_capability(state, "CanvasMode"); } void apply_canvas_mode_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) { pp::legacy::ui_gl::apply_viewport(x, y, width, height, "CanvasMode"); } std::uint32_t query_canvas_mode_read_framebuffer() { return pp::legacy::ui_gl::query_read_framebuffer("CanvasMode"); } void read_canvas_mode_pixel(std::int32_t x, std::int32_t y, glm::u8vec4& pixel) { pp::legacy::ui_gl::read_framebuffer_rgba8_pixel( query_canvas_mode_read_framebuffer(), x, y, &pixel, "CanvasMode"); } } void CanvasModeBasicCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: // if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) // { // m_draggingR = true; // m_dragR_start = me->m_pos; // m_pan_start = Canvas::I->m_pan; // node->mouse_capture(); // } if (App::I->keys[(int)kKey::KeySpacebar]) { m_draggingL = true; m_pan_start = Canvas::I->m_pan; m_dragL_start = me->m_pos; node->mouse_capture(); } break; case kEventType::MouseUpL: // if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) // { // m_draggingR = false; // node->mouse_release(); // } if (m_draggingL) { m_draggingL = false; pp::panopainter::release_legacy_mouse_capture(*node); } break; case kEventType::MouseDownR: if (App::I->keys[(int)kKey::KeyAlt]) break; m_zooming = App::I->keys[(int)kKey::KeyCtrl]; m_draggingR = true; m_dragR_start = me->m_pos; m_pan_start = Canvas::I->m_pan; m_fov_start = Canvas::I->m_cam_fov; node->mouse_capture(); break; case kEventType::MouseUpR: m_draggingR = false; pp::panopainter::release_legacy_mouse_capture(*node); break; case kEventType::MouseMove: if (m_draggingR) { if (m_zooming) { Canvas::I->m_cam_fov = glm::clamp(m_fov_start - (me->m_pos.x - m_dragR_start.x) * 0.05f, Canvas::I->m_cam_fov_min, Canvas::I->m_cam_fov_max); } else { const auto vr_session = App::I->vr_session_snapshot(); auto dir = (vr_session.has_vr && vr_session.vr_active) ? glm::vec2(1, 1) : glm::vec2(-1, -1); Canvas::I->m_pan = m_pan_start + (me->m_pos - m_dragR_start) * dir * (Canvas::I->m_cam_fov / 85.f); auto angle = Canvas::I->m_pan * 0.003f; Canvas::I->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); } } if (m_draggingL) { Canvas::I->m_pan = m_pan_start + (me->m_pos - m_dragL_start) * glm::vec2(-1, -1) * (Canvas::I->m_cam_fov / 85.f); auto angle = Canvas::I->m_pan * 0.003f; Canvas::I->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); } break; case kEventType::MouseScroll: m_zoom_canvas += me->m_scroll_delta * 0.1f; Canvas::I->m_cam_fov = glm::clamp(Canvas::I->m_cam_fov - me->m_scroll_delta * 2.0f, Canvas::I->m_cam_fov_min, Canvas::I->m_cam_fov_max); //App::I->brush_update(true, true); break; case kEventType::MouseCancel: m_draggingR = false; pp::panopainter::release_legacy_mouse_capture(*node); break; default: break; } } void CanvasModeBasicCamera::on_GestureEvent(GestureEvent* ge) { switch (ge->m_type) { case kEventType::GestureStart: m_pan_start = Canvas::I->m_pan; m_zoom_start = m_zoom_canvas; m_camera_fov = Canvas::I->m_cam_fov; break; case kEventType::GestureMove: { Canvas::I->m_pan = m_pan_start + ge->m_pos_delta * glm::vec2(-1, -1) * 0.3f * (Canvas::I->m_cam_fov / 85.f); Canvas::I->m_cam_fov = glm::clamp(m_camera_fov - ge->m_distance_delta * .05f, Canvas::I->m_cam_fov_min, Canvas::I->m_cam_fov_max); auto angle = Canvas::I->m_pan * 0.003f; Canvas::I->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); //App::I->brush_update(true, true); break; } default: break; } } void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { case kEventType::MouseDownR: Canvas::I->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseDownL: m_dragging = true; m_drag_start = me->m_pos; m_pos_start = xy(Canvas::I->m_cam_pos); node->mouse_capture(); break; case kEventType::MouseUpL: m_dragging = false; pp::panopainter::release_legacy_mouse_capture(*node); Canvas::I->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseMove: if (m_dragging) Canvas::I->m_cam_pos = glm::vec3(m_pos_start + (me->m_pos - m_drag_start) * glm::vec2(1, -1) * 0.001f, Canvas::I->m_cam_pos.z); break; case kEventType::MouseCancel: m_dragging = false; pp::panopainter::release_legacy_mouse_capture(*node); break; default: break; } } void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { case kEventType::MouseDownL: { node->mouse_capture(); glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 fb_pos; if (Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id)) { m_action = std::make_unique(); m_action->m_mode = this; m_action->m_highlight = m_highlight; m_action->m_selected_index = m_selected_index; m_action->m_lines = m_lines; int select = -1; for (int i = 0; i < m_lines.size(); i++) { auto const& l = m_lines[i]; float d = lines_distance(ro, ro + rd * 10.f, l.o - l.d * 10.f, l.o + l.d * 10.f); if (d < 0.03f) select = i; } if (select == -1) { m_lines.push_back({ hit_o, hit_d }); m_selected_index = (int)m_lines.size() - 1; m_highlight = false; m_added = true; } else { m_selected_index = select; m_highlight = true; m_added = false; } origin = hit_o; dir = hit_d; m_dragging = true; } break; } case kEventType::MouseUpL: pp::panopainter::release_legacy_mouse_capture(*node); m_dragging = false; ActionManager::add(m_action.release()); //commit(); break; case kEventType::MouseMove: { glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 hit_fb; if (m_dragging && Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, m_plane_id)) { m_lines[m_selected_index] = { hit_o, hit_d }; origin = hit_o; dir = hit_d; m_dragging = true; } break; } case kEventType::MouseCancel: if (m_dragging && m_selected_index == m_lines.size() - 1) m_lines.pop_back(); m_dragging = false; pp::panopainter::release_legacy_mouse_capture(*node); break; default: break; } } void CanvasModeGrid::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) { const glm::vec4 blue(0, 0, 1, 1); const glm::vec4 red(1, 0, 0, 1); for (int i = 0; i < m_lines.size(); i++) { auto const& l = m_lines[i]; auto origin = l.o; auto dir = l.d; pp::panopainter::setup_legacy_vr_color_shader({ .color = m_highlight && i == m_selected_index ? blue : red, .mvp = proj * camera, }); static glm::vec4 AB[2]; AB[0] = { origin - dir * 10.f, 1 }; AB[1] = { origin + dir * 10.f, 1 }; m_line.update_vertices(AB); m_line.draw_stroke(); } } void CanvasModeGrid::init() { m_line.create(); } void CanvasModeGrid::commit() { auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { pp::panopainter::setup_legacy_vr_color_shader({ .color = { 1, 0, 0, 1 }, .mvp = proj * camera, }); static glm::vec4 AB[2]; AB[0] = { origin - dir * 10.f, 1 }; AB[1] = { origin + dir * 10.f, 1 }; m_line.update_vertices(AB); m_line.draw_stroke(); }; Canvas::I->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->layer().m_frame_index, true); } void CanvasModeGrid::clear() { auto a = new ActionModeGrid; a->m_mode = this; a->m_highlight = m_highlight; a->m_selected_index = m_selected_index; a->m_lines = m_lines; ActionManager::add(a); m_lines.clear(); } void CanvasModeGrid::leave(kCanvasMode next) { m_selected_index = -1; } void CanvasModeGrid::on_KeyEvent(KeyEvent* ke) { if ((ke->m_key == kKey::KeyBackspace || ke->m_key == kKey::KeyDel) && ke->m_type == kEventType::KeyUp) { if (m_highlight) { auto a = new ActionModeGrid; a->m_mode = this; a->m_highlight = m_highlight; a->m_selected_index = m_selected_index; a->m_lines = m_lines; ActionManager::add(a); m_lines.erase(m_lines.begin() + m_selected_index); m_highlight = false; } } } Action* ActionModeGrid::get_redo() { auto a = new ActionModeGrid; a->m_mode = m_mode; a->m_highlight = m_mode->m_highlight; a->m_selected_index = m_mode->m_selected_index; a->m_lines = m_mode->m_lines; return a; } void ActionModeGrid::undo() { m_mode->m_highlight = m_highlight; m_mode->m_selected_index = m_selected_index; m_mode->m_lines = m_lines; }