improving brush tips browser, average stroke direction
This commit is contained in:
@@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
<!--brush-presets panel-->
|
<!--brush-presets panel-->
|
||||||
<layout id="tpl-panel-brush-preset">
|
<layout id="tpl-panel-brush-preset">
|
||||||
<node width="220" margin="0 0 10 0" rtl="ltr">
|
<node rtl="ltr">
|
||||||
<scroll id="brushes" color=".4" pad="5 20 5 5" dir="row" wrap="1" flood-events="1" grow="1" height="1"/>
|
<scroll id="brushes" color=".4" pad="5 20 5 5" dir="row" wrap="1" flood-events="1" grow="1" height="1"/>
|
||||||
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
||||||
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
||||||
@@ -121,13 +121,25 @@
|
|||||||
|
|
||||||
<!--brushes panel-->
|
<!--brushes panel-->
|
||||||
<layout id="tpl-panel-brushes">
|
<layout id="tpl-panel-brushes">
|
||||||
<node width="220" margin="0 0 10 0" rtl="ltr">
|
<node rtl="ltr">
|
||||||
<!--
|
<scroll id="brushes" color=".4" pad="5" dir="row" wrap="1" flood-events="1" grow="1" height="1"/>
|
||||||
<border height="30" color=".5" align="center" justify="center">
|
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
||||||
<text text="Brushes" font-face="arial" font-size="11" color="1 1 1 1"/>
|
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
||||||
</border>
|
<icon width="30" icon="add"/>
|
||||||
-->
|
</button-custom>
|
||||||
<border id="brushes" color=".4" pad="5" dir="row" wrap="1" flood-events="1">
|
<button-custom id="btn-up" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 0">
|
||||||
|
<icon width="30" icon="bullet_arrow_up"/>
|
||||||
|
</button-custom>
|
||||||
|
<button-custom id="btn-down" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 0">
|
||||||
|
<icon width="30" icon="bullet_arrow_down"/>
|
||||||
|
</button-custom>
|
||||||
|
<button-custom id="btn-save" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 0">
|
||||||
|
<icon width="30" icon="bullet_disk"/>
|
||||||
|
</button-custom>
|
||||||
|
<node grow="1"></node>
|
||||||
|
<button-custom id="btn-remove" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 10 0 0">
|
||||||
|
<icon width="30" icon="bin_closed"/>
|
||||||
|
</button-custom>
|
||||||
</border>
|
</border>
|
||||||
</node>
|
</node>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ void App::update(float dt)
|
|||||||
if (auto* main = layout[main_id])
|
if (auto* main = layout[main_id])
|
||||||
{
|
{
|
||||||
main->update(width, height, zoom);
|
main->update(width, height, zoom);
|
||||||
stroke->update_controls();
|
//stroke->update_controls();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,22 +170,31 @@ std::vector<StrokeSample> Stroke::compute_samples()
|
|||||||
float pressure = glm::lerp(A.pressure, B.pressure, t);
|
float pressure = glm::lerp(A.pressure, B.pressure, t);
|
||||||
|
|
||||||
auto s = randomize_sample(pos, pressure, 0);
|
auto s = randomize_sample(pos, pressure, 0);
|
||||||
if (m_brush->m_tip_angle_follow)
|
if (s.valid())
|
||||||
{
|
{
|
||||||
auto& pre = m_prev_sample;
|
if (m_brush->m_tip_angle_follow)
|
||||||
glm::vec2 v = glm::normalize(s.origin - pre.origin);
|
{
|
||||||
float curve_angle = -glm::orientedAngle(v, glm::vec2(1, 0));
|
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
|
// NOTE: average angles need correction for 0-360 discontinuity
|
||||||
//m_curve_angles.add(curve_angle);
|
//m_curve_angles.add(curve_angle);
|
||||||
//float avg = m_curve_angles.average();
|
//float avg = m_curve_angles.average();
|
||||||
|
|
||||||
s.angle += curve_angle;
|
s.angle += curve_angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_prev_sample = s;
|
||||||
|
samples.push_back(s);
|
||||||
}
|
}
|
||||||
m_prev_sample = s;
|
else
|
||||||
if (!s.valid())
|
{
|
||||||
LOG("Invalid sample");
|
LOG("Invalid sample");
|
||||||
samples.push_back(s);
|
}
|
||||||
}
|
}
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
@@ -237,7 +246,7 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
|
|||||||
{
|
{
|
||||||
m_hold_points.clear();
|
m_hold_points.clear();
|
||||||
m_curve = 0.f;
|
m_curve = 0.f;
|
||||||
m_curve_angles.clear();
|
m_direction.clear();
|
||||||
m_pressure_buff.clear();
|
m_pressure_buff.clear();
|
||||||
m_hsv_jitter.clear();
|
m_hsv_jitter.clear();
|
||||||
m_last_kp = 0;
|
m_last_kp = 0;
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ struct StrokeSample
|
|||||||
bool valid() const
|
bool valid() const
|
||||||
{
|
{
|
||||||
return !(
|
return !(
|
||||||
|
glm::isnan(angle) ||
|
||||||
|
glm::isinf(angle) ||
|
||||||
glm::any(glm::isnan(col)) ||
|
glm::any(glm::isnan(col)) ||
|
||||||
glm::any(glm::isnan(pos)) ||
|
glm::any(glm::isnan(pos)) ||
|
||||||
glm::any(glm::isnan(origin))
|
glm::any(glm::isnan(origin))
|
||||||
@@ -100,7 +102,7 @@ public:
|
|||||||
bool m_filter_points = true;
|
bool m_filter_points = true;
|
||||||
Camera m_camera;
|
Camera m_camera;
|
||||||
std::shared_ptr<Brush> m_brush;
|
std::shared_ptr<Brush> m_brush;
|
||||||
cbuffer<float, 3> m_curve_angles;
|
cbuffer<glm::vec2, 3> m_direction;
|
||||||
cbuffer<float, 10> m_pressure_buff;
|
cbuffer<float, 10> m_pressure_buff;
|
||||||
cbuffer<glm::vec3, 3> m_hsv_jitter;
|
cbuffer<glm::vec3, 3> m_hsv_jitter;
|
||||||
StrokeSample m_prev_sample;
|
StrokeSample m_prev_sample;
|
||||||
|
|||||||
@@ -411,6 +411,9 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
for (const auto& s : samples)
|
for (const auto& s : samples)
|
||||||
{
|
{
|
||||||
|
if (!s.valid())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (m_mixer_idle)
|
if (m_mixer_idle)
|
||||||
{
|
{
|
||||||
m_mixer_sample = s;
|
m_mixer_sample = s;
|
||||||
|
|||||||
@@ -178,6 +178,8 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
{
|
{
|
||||||
auto diff = m_cur_pos - m_size_pos_start;
|
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);
|
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;
|
m_cur_pos = loc;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -204,13 +204,19 @@ void NodePanelBrushPreset::init()
|
|||||||
m_btn_up = find<NodeButtonCustom>("btn-up");
|
m_btn_up = find<NodeButtonCustom>("btn-up");
|
||||||
m_btn_up->on_click = [this](Node*) {
|
m_btn_up->on_click = [this](Node*) {
|
||||||
if (m_current)
|
if (m_current)
|
||||||
|
{
|
||||||
m_container->move_child(m_current, std::max(m_container->get_child_index(m_current) - 1, 0));
|
m_container->move_child(m_current, std::max(m_container->get_child_index(m_current) - 1, 0));
|
||||||
|
save();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
m_btn_down = find<NodeButtonCustom>("btn-down");
|
m_btn_down = find<NodeButtonCustom>("btn-down");
|
||||||
m_btn_down->on_click = [this](Node*) {
|
m_btn_down->on_click = [this](Node*) {
|
||||||
if (m_current)
|
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));
|
std::min(m_container->get_child_index(m_current) + 1, (int)m_container->m_children.size() - 1));
|
||||||
|
save();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
m_btn_save = find<NodeButtonCustom>("btn-save");
|
m_btn_save = find<NodeButtonCustom>("btn-save");
|
||||||
m_btn_save->on_click = [this](Node*) {
|
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_brush = *Canvas::I->m_current_brush;
|
||||||
m_current->m_preview->draw_stroke();
|
m_current->m_preview->draw_stroke();
|
||||||
m_current->m_thumb->set_image(m_current->m_brush->m_brush_thumb_path);
|
m_current->m_thumb->set_image(m_current->m_brush->m_brush_thumb_path);
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
m_btn_delete = find<NodeButtonCustom>("btn-remove");
|
m_btn_delete = find<NodeButtonCustom>("btn-remove");
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ void NodePanelStroke::init_controls()
|
|||||||
m_brush_popup->create();
|
m_brush_popup->create();
|
||||||
m_brush_popup->loaded();
|
m_brush_popup->loaded();
|
||||||
m_brush_popup->SetPositioning(YGPositionTypeAbsolute);
|
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_mouse_ignore = false;
|
||||||
m_brush_popup->m_flood_events = true;
|
m_brush_popup->m_flood_events = true;
|
||||||
m_brush_popup->m_capture_children = false;
|
m_brush_popup->m_capture_children = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user