#include "pch.h" #include "log.h" #include "canvas_modes.h" #include "layout.h" #include "canvas.h" #include "shader.h" #include "node_canvas.h" NodeCanvas* CanvasMode::node; ui::Canvas* CanvasMode::canvas; void CanvasModeBasicCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: break; case kEventType::MouseUpL: break; case kEventType::MouseDownR: m_draggingR = true; m_dragR_start = me->m_pos; m_pan_start = canvas->m_pan; node->mouse_capture(); break; case kEventType::MouseUpR: m_draggingR = false; node->mouse_release(); break; case kEventType::MouseMove: if (m_draggingR) canvas->m_pan = m_pan_start + (me->m_pos - m_dragR_start) * glm::vec2(-1, -1); canvas->m_cam_rot = canvas->m_pan * 0.003f; break; case kEventType::MouseScroll: m_zoom_canvas += me->m_scroll_delta * 0.1f; canvas->m_cam_fov -= me->m_scroll_delta * 20.1f; break; case kEventType::MouseCancel: m_draggingR = false; node->mouse_release(); break; default: break; } } void CanvasModeBasicCamera::on_GestureEvent(GestureEvent* ge) { switch (ge->m_type) { case kEventType::GestureStart: m_pan_start = canvas->m_pan; m_zoom_start = m_zoom_canvas; m_camera_fov = canvas->m_cam_fov; break; case kEventType::GestureMove: canvas->m_pan = m_pan_start + ge->m_pos_delta * glm::vec2(-1, -1) * 0.3f; canvas->m_cam_fov = m_camera_fov - ge->m_distance_delta * .05f; canvas->m_cam_rot = canvas->m_pan * 0.003f; break; default: break; } } //////////////////////////////////////////////////////////////////// void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: canvas->stroke_start(loc, me->m_pressure, node->m_brush); m_dragging = true; node->mouse_capture(); break; case kEventType::MouseUpL: canvas->stroke_end(); m_dragging = false; node->mouse_release(); break; case kEventType::MouseMove: if (m_dragging) canvas->stroke_update(loc, me->m_pressure); break; case kEventType::MouseCancel: canvas->stroke_cancel(); m_dragging = false; node->mouse_release(); break; default: break; } } //////////////////////////////////////////////////////////////////// void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: node->mouse_capture(); m_dragging = true; m_drag_start = loc; m_drag_pos = loc; break; case kEventType::MouseUpL: node->mouse_release(); if (m_dragging) { canvas->stroke_start(m_drag_start, 1.f, node->m_brush); canvas->stroke_update(m_drag_pos, 1.f); canvas->stroke_end(); } m_dragging = false; break; case kEventType::MouseMove: if (m_dragging) m_drag_pos = loc; break; case kEventType::MouseCancel: node->mouse_release(); m_dragging = false; break; default: break; } } void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) { if (m_dragging) { ui::ShaderManager::use(ui::kShader::Color); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, node->m_brush.m_tip_color); static glm::vec4 AB[2]; AB[0] = { m_drag_start, 0, 1 }; AB[1] = { m_drag_pos, 0, 1 }; AB[0].y = canvas->m_box.w - AB[0].y - 1; // invert Y AB[1].y = canvas->m_box.w - AB[1].y - 1; // invert Y m_line.update_vertices(AB); m_line.draw_stroke(); } } void CanvasModeLine::init() { m_line.create(); } //////////////////////////////////////////////////////////////////// void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownR: canvas->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseDownL: m_dragging = true; m_drag_start = me->m_pos; m_pos_start = canvas->m_cam_pos.xy; node->mouse_capture(); break; case kEventType::MouseUpL: m_dragging = false; node->mouse_release(); canvas->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseMove: if (m_dragging) canvas->m_cam_pos.xy = m_pos_start + (me->m_pos - m_drag_start) * glm::vec2(1, -1) * 0.001f; break; case kEventType::MouseCancel: m_dragging = false; node->mouse_release(); break; default: break; } } //////////////////////////////////////////////////////////////////// void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: { node->mouse_capture(); glm::vec3 ro, rd, hit_o, hit_d; if (canvas->point_trace(loc, ro, rd, hit_o, hit_d, m_plane_id)) { m_lines.push_back({ hit_o, hit_d }); origin = hit_o; dir = hit_d; m_dragging = true; } break; } case kEventType::MouseUpL: node->mouse_release(); m_dragging = false; //commit(); break; case kEventType::MouseMove: { glm::vec3 ro, rd, hit_o, hit_d; if (m_dragging && canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, m_plane_id)) { m_lines.back() = { hit_o, hit_d }; origin = hit_o; dir = hit_d; m_dragging = true; } break; } case kEventType::MouseCancel: if (m_dragging) m_lines.pop_back(); m_dragging = false; node->mouse_release(); break; default: break; } } void CanvasModeGrid::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) { //if (m_dragging) for (auto l : m_lines) { auto origin = l.o; auto dir = l.d; ui::ShaderManager::use(ui::kShader::Color); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, {1, 0, 0, 1}); 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){ ui::ShaderManager::use(ui::kShader::Color); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, {1, 0, 0, 1}); 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->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2)); } void CanvasModeGrid::clear() { m_lines.clear(); } //////////////////////////////////////////////////////////////////// void CanvasModeFill::init() { m_shape.create(); } void CanvasModeFill::leave() { canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(), std::placeholders::_1, std::placeholders::_2)); m_points.clear(); } void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownR: { auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { ui::ShaderManager::use(ui::kShader::Color); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { node->m_brush.m_tip_color.rgb(), node->m_brush.m_tip_opacity }); m_shape.draw_fill(); }; canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2)); m_points.clear(); break; } case kEventType::MouseDownL: { node->mouse_capture(); m_dragging = true; glm::vec3 ro, rd, hit_o, hit_d; int plane_id; if (canvas->point_trace(loc, ro, rd, hit_o, hit_d, plane_id)) { ui::Shape::vertex_t v; v.pos = glm::vec4(hit_o, 1); v.uvs = glm::vec2(0); if (m_points.size() < 3) { m_points.push_back(v); } else { auto last = m_points.back(); m_points.push_back(m_points[0]); m_points.push_back(last); m_points.push_back(v); } m_shape.update_vertices(m_points.data(), m_points.size()); } break; } case kEventType::MouseUpL: node->mouse_release(); m_dragging = false; break; case kEventType::MouseMove: { glm::vec3 ro, rd, hit_o, hit_d; int plane_id; if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, hit_d, plane_id)) { ui::Shape::vertex_t v; v.pos = glm::vec4(hit_o, 1); v.uvs = glm::vec2(0); m_points.back() = v; m_shape.update_vertices(m_points.data(), m_points.size()); } break; } case kEventType::MouseCancel: if (m_dragging) { m_points.pop_back(); m_shape.update_vertices(m_points.data(), m_points.size()); } m_dragging = false; node->mouse_release(); if (m_points.size() < 4) { m_points.clear(); m_shape.update_vertices(m_points.data(), m_points.size()); } break; default: break; } } void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) { if (!m_points.empty()) { ui::ShaderManager::use(ui::kShader::Color); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { node->m_brush.m_tip_color.rgb(), node->m_brush.m_tip_opacity }); m_shape.draw_fill(); } }