From f7b156acaa329f55aae620dcb7cb6b07fa473a81 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 26 Feb 2019 20:03:01 +0100 Subject: [PATCH] rename jitter spread to scatter, dual brush scatter mode single and both axis, fix scatter to follow the direction --- data/layout.xml | 14 ++++--- src/abr.cpp | 2 +- src/brush.cpp | 80 ++++++++++++++++++++----------------- src/brush.h | 12 +++++- src/canvas.cpp | 3 +- src/node_panel_brush.cpp | 12 +++--- src/node_panel_brush.h | 5 ++- src/node_panel_stroke.cpp | 9 +++-- src/node_panel_stroke.h | 5 ++- src/node_stroke_preview.cpp | 3 +- 10 files changed, 86 insertions(+), 59 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 2bbef3b..9393398 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -459,7 +459,7 @@ - + @@ -558,8 +558,8 @@ - - + + @@ -590,8 +590,12 @@ - - + + + + + + diff --git a/src/abr.cpp b/src/abr.cpp index 5d4dba6..baedeaa 100644 --- a/src/abr.cpp +++ b/src/abr.cpp @@ -291,7 +291,7 @@ std::vector> ABR::compute_brushes(const std::string& path b->m_tip_flipy = samp->value("flipY"); b->m_dual_randflip = db->value("Flip"); - b->m_dual_scatter_axis = db->value("bothAxes"); + b->m_dual_scatter_bothaxis = db->value("bothAxes"); if (db->value("useScatter")) { diff --git a/src/brush.cpp b/src/brush.cpp index 1da8b39..4f86c26 100644 --- a/src/brush.cpp +++ b/src/brush.cpp @@ -126,7 +126,7 @@ bool BrushMesh::create() return true; } -StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float curve_angle) +StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float dir_angle) { auto rnd_nor = [&] { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1] auto rnd_neg = [&] { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1] @@ -140,6 +140,8 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa float size = glm::min(m_brush->m_tip_size / glm::tan(glm::radians(m_camera.fov * 0.5f)), m_max_size); float randflipx = m_brush->m_tip_randflipx ? rnd_bneg() : 1.f; float randflipy = m_brush->m_tip_randflipy ? rnd_bneg() : 1.f; + glm::vec2 scatter_axis = m_brush->m_jitter_scatter_bothaxis ? glm::vec2(1.f, 1.f) : glm::vec2(0.f, 1.f); + auto scatter_scale = glm::vec3(scatter_axis * glm::orientate2(-dir_angle), 1.f); StrokeSample s; s.scale.x = m_brush->m_tip_scale.x * randflipx * (m_brush->m_tip_flipx ? -1.f : 1.f) * @@ -147,9 +149,9 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa s.scale.y = m_brush->m_tip_scale.y * randflipy * (m_brush->m_tip_flipy ? -1.f : 1.f) * (m_brush->m_tip_aspect > 0.5 ? 1.f - (m_brush->m_tip_aspect - .5f) * 2.f : 1.f); s.origin = pos; - s.angle = -curve_angle + (m_brush->m_tip_angle + rnd_neg() * m_brush->m_jitter_angle) * (float)(M_PI * 2.0); + s.angle = (m_brush->m_tip_angle + rnd_neg() * m_brush->m_jitter_angle) * (float)(M_PI * 2.0); s.size = size * (1.f - rnd_nor() * m_brush->m_jitter_scale) * size_dyn; - s.pos = pos + (rnd_vec() * m_brush->m_jitter_spread * s.size); + s.pos = pos + (scatter_scale * rnd_vec() * m_brush->m_jitter_scatter * s.size); s.flow = m_brush->m_tip_flow * (1.f - rnd_nor() * m_brush->m_jitter_flow) * flow_dyn; s.opacity = m_brush->m_tip_opacity * (1.f - rnd_nor() * m_brush->m_jitter_opacity) * opacity_dyn; auto hsv = convert_rgb2hsv(m_brush->m_tip_color); @@ -179,43 +181,49 @@ std::vector Stroke::compute_samples() auto pos = glm::lerp(A.pos, B.pos, t); float pressure = glm::lerp(A.pressure, B.pressure, t); - auto s = randomize_sample(pos, pressure, 0); + if (m_dir_dist > m_dir_step && m_last_kp != m_dir_kp) + { + glm::vec2 v = glm::normalize(m_keypoints[m_last_kp].pos - m_keypoints[m_dir_kp].pos); + m_dir_angle = -glm::orientedAngle(v, m_dir_ref); + if (m_brush->m_tip_angle_smooth > 0 && (glm::abs(m_dir_angle) > glm::radians(30.f) || !m_dir_valid)) + { + if (glm::abs(m_dir_angle) > glm::radians(100.f)) + { + //LOG("BIG ANGLE"); + m_direction.clear(); + } + + auto old_dir = m_dir_ref; + m_dir_ref = v; + m_dir_ref_angle = -glm::orientedAngle(m_dir_ref, { 1, 0 }); + m_dir_angle = 0; + auto angle_diff = -glm::orientedAngle(m_dir_ref, old_dir); + for (int i = 0; i < m_direction.m_count; i++) + m_direction.m_vec[i] -= angle_diff; + } + m_dir_kp = m_last_kp; + m_dir_dist = 0; + m_dir_valid = true; + } + + bool need_dir = false; + need_dir |= m_brush->m_tip_angle_follow; + need_dir |= m_brush->m_tip_angle_init; + need_dir |= m_brush->m_jitter_angle > 0; + + // angle is not ready yet + if (need_dir && !m_dir_valid) + continue; + + auto s = randomize_sample(pos, pressure, m_dir_angle + m_dir_ref_angle); if (s.valid()) { if (m_brush->m_tip_angle_follow || (!m_dir_valid && m_brush->m_tip_angle_init)) { - if (m_dir_dist > m_dir_step && m_last_kp != m_dir_kp) - { - glm::vec2 v = glm::normalize(m_keypoints[m_last_kp].pos - m_keypoints[m_dir_kp].pos); - m_dir_angle = -glm::orientedAngle(v, m_dir_ref); - if (m_brush->m_tip_angle_smooth > 0 && (glm::abs(m_dir_angle) > glm::radians(30.f) || !m_dir_valid)) - { - if (glm::abs(m_dir_angle) > glm::radians(100.f)) - { - //LOG("BIG ANGLE"); - m_direction.clear(); - } - - auto old_dir = m_dir_ref; - m_dir_ref = v; - m_dir_ref_angle = -glm::orientedAngle(m_dir_ref, { 1, 0 }); - m_dir_angle = 0; - auto angle_diff = -glm::orientedAngle(m_dir_ref, old_dir); - for (int i = 0; i < m_direction.m_count; i++) - m_direction.m_vec[i] -= angle_diff; - } - m_dir_kp = m_last_kp; - m_dir_dist = 0; - m_dir_valid = true; - } - - if (m_dir_valid) - { - m_direction.add(m_dir_angle); - s.angle += m_direction.average() + m_dir_ref_angle; - m_prev_sample = s; - samples.push_back(s); - } + m_direction.add(m_dir_angle); + s.angle += m_direction.average() + m_dir_ref_angle; + m_prev_sample = s; + samples.push_back(s); } else { diff --git a/src/brush.h b/src/brush.h index 0007441..08d7d79 100644 --- a/src/brush.h +++ b/src/brush.h @@ -43,7 +43,8 @@ public: bool m_tip_size_pressure = false; float m_jitter_scale = 0; float m_jitter_angle = 0; - float m_jitter_spread = 0; + float m_jitter_scatter = 0; + bool m_jitter_scatter_bothaxis = false; float m_jitter_flow = 0; float m_jitter_opacity = 0; float m_jitter_hue = 0; @@ -61,7 +62,7 @@ public: float m_dual_size = .75; float m_dual_spacing = .25; float m_dual_scatter = 0; - bool m_dual_scatter_axis = false; + bool m_dual_scatter_bothaxis = false; bool m_dual_invert = false; bool m_dual_flipx = false; bool m_dual_flipy = false; @@ -107,8 +108,15 @@ struct StrokeSample return !( glm::isnan(angle) || glm::isinf(angle) || + glm::isnan(flow) || + glm::isinf(flow) || + glm::isnan(opacity) || + glm::isinf(opacity) || + glm::isnan(size) || + glm::isinf(size) || glm::any(glm::isnan(col)) || glm::any(glm::isnan(pos)) || + glm::any(glm::isnan(scale)) || glm::any(glm::isnan(origin)) ); } diff --git a/src/canvas.cpp b/src/canvas.cpp index 39517c9..a06135e 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -917,7 +917,8 @@ void Canvas::stroke_start(glm::vec3 point, float pressure) dual_brush->m_tip_randflipy = m_current_brush->m_dual_randflip; dual_brush->m_tip_size = m_current_brush->m_dual_size * m_current_brush->m_tip_size; dual_brush->m_tip_spacing = m_current_brush->m_dual_spacing; - dual_brush->m_jitter_spread = m_current_brush->m_dual_scatter; + dual_brush->m_jitter_scatter = m_current_brush->m_dual_scatter; + dual_brush->m_jitter_scatter_bothaxis = m_current_brush->m_dual_scatter_bothaxis; dual_brush->m_jitter_angle = m_current_brush->m_dual_rotate; dual_brush->m_tip_texture = m_current_brush->m_dual_texture; m_dual_stroke = std::make_unique(); diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index c08b104..de56679 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -505,7 +505,8 @@ bool NodePanelBrushPreset::save() i.m_tip_size_pressure = b->m_tip_size_pressure; i.m_jitter_scale = b->m_jitter_scale; i.m_jitter_angle = b->m_jitter_angle; - i.m_jitter_spread = b->m_jitter_spread; + i.m_jitter_scatter = b->m_jitter_scatter; + i.m_jitter_scatter_bothaxis = b->m_jitter_scatter_bothaxis; i.m_jitter_flow = b->m_jitter_flow; i.m_jitter_opacity = b->m_jitter_opacity; i.m_jitter_hue = b->m_jitter_hue; @@ -523,7 +524,7 @@ bool NodePanelBrushPreset::save() i.m_dual_size = b->m_dual_size; i.m_dual_spacing = b->m_dual_spacing; i.m_dual_scatter = b->m_dual_scatter; - i.m_dual_scatter_axis = b->m_dual_scatter_axis; + i.m_dual_scatter_bothaxis = b->m_dual_scatter_bothaxis; i.m_dual_invert = b->m_dual_invert; i.m_dual_flipx = b->m_dual_flipx; i.m_dual_flipy = b->m_dual_flipy; @@ -608,8 +609,9 @@ bool NodePanelBrushPreset::restore() b->m_tip_size_pressure = i.m_tip_size_pressure; b->m_jitter_scale = i.m_jitter_scale; b->m_jitter_angle = i.m_jitter_angle; - b->m_jitter_spread = i.m_jitter_spread; - b->m_jitter_flow = i.m_jitter_flow; + b->m_jitter_scatter = i.m_jitter_scatter; + b->m_jitter_scatter_bothaxis = i.m_jitter_scatter_bothaxis; + b->m_jitter_flow = i.m_jitter_flow; b->m_jitter_opacity = i.m_jitter_opacity; b->m_jitter_hue = i.m_jitter_hue; b->m_jitter_sat = i.m_jitter_sat; @@ -626,7 +628,7 @@ bool NodePanelBrushPreset::restore() b->m_dual_size = i.m_dual_size; b->m_dual_spacing = i.m_dual_spacing; b->m_dual_scatter = i.m_dual_scatter; - b->m_dual_scatter_axis = i.m_dual_scatter_axis; + b->m_dual_scatter_bothaxis = i.m_dual_scatter_bothaxis; b->m_dual_invert = i.m_dual_invert; b->m_dual_flipx = i.m_dual_flipx; b->m_dual_flipy = i.m_dual_flipy; diff --git a/src/node_panel_brush.h b/src/node_panel_brush.h index 4e58591..787a269 100644 --- a/src/node_panel_brush.h +++ b/src/node_panel_brush.h @@ -124,7 +124,8 @@ class NodePanelBrushPreset : public Node bool m_tip_size_pressure = false; float m_jitter_scale = 0; float m_jitter_angle = 0; - float m_jitter_spread = 0; + float m_jitter_scatter = 0; + bool m_jitter_scatter_bothaxis = false; float m_jitter_flow = 0; float m_jitter_opacity = 0; float m_jitter_hue = 0; @@ -142,7 +143,7 @@ class NodePanelBrushPreset : public Node float m_dual_size = 0; float m_dual_spacing = 0; float m_dual_scatter = 0; - bool m_dual_scatter_axis = false; + bool m_dual_scatter_bothaxis = false; bool m_dual_invert = false; bool m_dual_flipx = false; bool m_dual_flipy = false; diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index 091be79..93e3b23 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -158,7 +158,7 @@ void NodePanelStroke::update_controls() m_tip_noise->m_value.x = b->m_tip_noise; m_jitter_scale->m_value.x = b->m_jitter_scale; m_jitter_angle->m_value.x = b->m_jitter_angle; - m_jitter_spread->m_value.x = b->m_jitter_spread; + m_jitter_scatter->m_value.x = b->m_jitter_scatter; m_jitter_flow->m_value.x = b->m_jitter_flow; m_jitter_opacity->m_value.x = b->m_jitter_opacity; m_jitter_hue->m_value.x = b->m_jitter_hue; @@ -173,7 +173,7 @@ void NodePanelStroke::update_controls() m_tip_flipy->checked = b->m_tip_flipy; m_pattern_enabled->checked = b->m_pattern_enabled; m_dual_enabled->checked = b->m_dual_enabled; - m_dual_scatter_axis->checked = b->m_dual_scatter_axis; + m_dual_scatter_bothaxis->checked = b->m_dual_scatter_bothaxis; m_dual_invert->checked = b->m_dual_invert; m_dual_flipx->checked = b->m_dual_flipx; m_dual_flipy->checked = b->m_dual_flipy; @@ -435,7 +435,7 @@ void NodePanelStroke::init_controls() init_slider(m_tip_val, "tip-val", &Brush::m_tip_val); init_slider(m_jitter_scale, "jitter-scale", &Brush::m_jitter_scale); init_slider(m_jitter_angle, "jitter-angle", &Brush::m_jitter_angle); - init_slider(m_jitter_spread, "jitter-spread", &Brush::m_jitter_spread); + init_slider(m_jitter_scatter, "jitter-scatter", &Brush::m_jitter_scatter); init_slider(m_jitter_flow, "jitter-flow", &Brush::m_jitter_flow); init_slider(m_jitter_opacity, "jitter-opacity", &Brush::m_jitter_opacity); init_slider(m_jitter_hue, "jitter-hue", &Brush::m_jitter_hue); @@ -447,13 +447,14 @@ void NodePanelStroke::init_controls() init_checkbox(m_tip_flow_pressure, "tip-flow-pressure", &Brush::m_tip_flow_pressure); init_checkbox(m_tip_opacity_pressure, "tip-opacity-pressure", &Brush::m_tip_opacity_pressure); init_checkbox(m_tip_size_pressure, "tip-size-pressure", &Brush::m_tip_size_pressure); + init_checkbox(m_jitter_scatter_bothaxis, "jitter-scatter-bothaxis", &Brush::m_jitter_scatter_bothaxis); init_checkbox(m_tip_invert, "tip-invert", &Brush::m_tip_invert); init_checkbox(m_tip_flipx, "tip-flipx", &Brush::m_tip_flipx); init_checkbox(m_tip_flipy, "tip-flipy", &Brush::m_tip_flipy); init_checkbox(m_pattern_enabled, "pattern-enabled", &Brush::m_pattern_enabled); init_checkbox(m_dual_enabled, "dual-enabled", &Brush::m_dual_enabled); - init_checkbox(m_dual_scatter_axis, "dual-scatter-axis", &Brush::m_dual_scatter_axis); + init_checkbox(m_dual_scatter_bothaxis, "dual-scatter-bothaxis", &Brush::m_dual_scatter_bothaxis); init_checkbox(m_dual_invert, "dual-invert", &Brush::m_dual_invert); init_checkbox(m_dual_flipx, "dual-flipx", &Brush::m_dual_flipx); init_checkbox(m_dual_flipy, "dual-flipy", &Brush::m_dual_flipy); diff --git a/src/node_panel_stroke.h b/src/node_panel_stroke.h index 4c881ff..06f064f 100644 --- a/src/node_panel_stroke.h +++ b/src/node_panel_stroke.h @@ -28,7 +28,7 @@ public: NodeSliderH* m_tip_val; NodeSliderH* m_jitter_scale; NodeSliderH* m_jitter_angle; - NodeSliderH* m_jitter_spread; + NodeSliderH* m_jitter_scatter; NodeSliderH* m_jitter_flow; NodeSliderH* m_jitter_opacity; NodeSliderH* m_jitter_hue; @@ -39,6 +39,7 @@ public: NodeCheckBox* m_tip_flow_pressure; NodeCheckBox* m_tip_opacity_pressure; NodeCheckBox* m_tip_size_pressure; + NodeCheckBox* m_jitter_scatter_bothaxis; NodeButtonCustom* m_brush_button; NodeButtonCustom* m_dual_brush_button; NodeButtonCustom* m_pattern_button; @@ -52,7 +53,7 @@ public: NodeCheckBox* m_tip_flipy; NodeCheckBox* m_pattern_enabled; NodeCheckBox* m_dual_enabled; - NodeCheckBox* m_dual_scatter_axis; + NodeCheckBox* m_dual_scatter_bothaxis; NodeCheckBox* m_dual_invert; NodeCheckBox* m_dual_flipx; NodeCheckBox* m_dual_flipy; diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 106005a..2364a49 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -265,7 +265,8 @@ void NodeStrokePreview::draw_stroke() dual_brush->m_tip_randflipy = b->m_dual_randflip; dual_brush->m_tip_size = b->m_dual_size * b->m_tip_size; dual_brush->m_tip_spacing = b->m_dual_spacing; - dual_brush->m_jitter_spread = b->m_dual_scatter; + dual_brush->m_jitter_scatter = b->m_dual_scatter; + dual_brush->m_jitter_scatter_bothaxis = b->m_dual_scatter_bothaxis; dual_brush->m_jitter_angle = b->m_dual_rotate; dual_brush->m_tip_texture = b->m_dual_texture;