diff --git a/data/layout.xml b/data/layout.xml index cf6085a..743adf5 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -87,7 +87,7 @@ - + @@ -121,13 +121,25 @@ - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/app.cpp b/src/app.cpp index 39ccf52..4ad1d87 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -471,7 +471,7 @@ void App::update(float dt) if (auto* main = layout[main_id]) { main->update(width, height, zoom); - stroke->update_controls(); + //stroke->update_controls(); } } diff --git a/src/brush.cpp b/src/brush.cpp index a3a58c8..f044a13 100644 --- a/src/brush.cpp +++ b/src/brush.cpp @@ -170,22 +170,31 @@ std::vector Stroke::compute_samples() float pressure = glm::lerp(A.pressure, B.pressure, t); auto s = randomize_sample(pos, pressure, 0); - if (m_brush->m_tip_angle_follow) + if (s.valid()) { - auto& pre = m_prev_sample; - glm::vec2 v = glm::normalize(s.origin - pre.origin); - float curve_angle = -glm::orientedAngle(v, glm::vec2(1, 0)); - - // NOTE: average angles need correction for 0-360 discontinuity - //m_curve_angles.add(curve_angle); - //float avg = m_curve_angles.average(); - - s.angle += curve_angle; + if (m_brush->m_tip_angle_follow) + { + glm::vec2 v = s.origin - m_prev_sample.origin; + if (v.length() > 0) + { + m_direction.add((v)); + auto avg = m_direction.average(); + float curve_angle = -glm::orientedAngle(glm::normalize(avg), glm::vec2(1, 0)); + + // NOTE: average angles need correction for 0-360 discontinuity + //m_curve_angles.add(curve_angle); + //float avg = m_curve_angles.average(); + + s.angle += curve_angle; + } + } + m_prev_sample = s; + samples.push_back(s); } - m_prev_sample = s; - if (!s.valid()) + else + { LOG("Invalid sample"); - samples.push_back(s); + } } return samples; } @@ -237,7 +246,7 @@ void Stroke::start(const std::shared_ptr& brush) { m_hold_points.clear(); m_curve = 0.f; - m_curve_angles.clear(); + m_direction.clear(); m_pressure_buff.clear(); m_hsv_jitter.clear(); m_last_kp = 0; diff --git a/src/brush.h b/src/brush.h index e861162..0d1c7b9 100644 --- a/src/brush.h +++ b/src/brush.h @@ -58,6 +58,8 @@ struct StrokeSample bool valid() const { return !( + glm::isnan(angle) || + glm::isinf(angle) || glm::any(glm::isnan(col)) || glm::any(glm::isnan(pos)) || glm::any(glm::isnan(origin)) @@ -100,7 +102,7 @@ public: bool m_filter_points = true; Camera m_camera; std::shared_ptr m_brush; - cbuffer m_curve_angles; + cbuffer m_direction; cbuffer m_pressure_buff; cbuffer m_hsv_jitter; StrokeSample m_prev_sample; diff --git a/src/canvas.cpp b/src/canvas.cpp index 7f6fb7f..fb61b9d 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -411,6 +411,9 @@ void Canvas::stroke_draw() for (const auto& s : samples) { + if (!s.valid()) + continue; + if (m_mixer_idle) { m_mixer_sample = s; diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index c79a984..9bac5a5 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -178,6 +178,8 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { auto diff = m_cur_pos - m_size_pos_start; canvas->m_current_brush->m_tip_size = glm::max(m_size_value_start + diff.x * 0.001f, 0.001f); + if (App::I.stroke) + App::I.stroke->update_controls(); } m_cur_pos = loc; break; diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 8599ba6..f45040f 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -204,13 +204,19 @@ void NodePanelBrushPreset::init() m_btn_up = find("btn-up"); m_btn_up->on_click = [this](Node*) { if (m_current) + { m_container->move_child(m_current, std::max(m_container->get_child_index(m_current) - 1, 0)); + save(); + } }; m_btn_down = find("btn-down"); m_btn_down->on_click = [this](Node*) { if (m_current) - m_container->move_child(m_current, + { + m_container->move_child(m_current, std::min(m_container->get_child_index(m_current) + 1, (int)m_container->m_children.size() - 1)); + save(); + } }; m_btn_save = find("btn-save"); m_btn_save->on_click = [this](Node*) { @@ -219,6 +225,7 @@ void NodePanelBrushPreset::init() *m_current->m_brush = *Canvas::I->m_current_brush; m_current->m_preview->draw_stroke(); m_current->m_thumb->set_image(m_current->m_brush->m_brush_thumb_path); + save(); } }; m_btn_delete = find("btn-remove"); diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index dbf62b5..55a2257 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -55,7 +55,7 @@ void NodePanelStroke::init_controls() m_brush_popup->create(); m_brush_popup->loaded(); m_brush_popup->SetPositioning(YGPositionTypeAbsolute); - m_brush_popup->SetSize(400, 400); + m_brush_popup->SetSize(300, 400); m_brush_popup->m_mouse_ignore = false; m_brush_popup->m_flood_events = true; m_brush_popup->m_capture_children = false;