pixel based brush size, Photoshop slider curve, improve abr import
This commit is contained in:
@@ -63,8 +63,9 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
||||
std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png";
|
||||
std::string path_thumb = App::I.data_path + "/brushes/thumbs/" + samp.first + ".png";
|
||||
auto padded = samp.second->resize_squared(glm::u8vec4(255));
|
||||
auto high = padded.resize_power2();
|
||||
high.save(path_high);
|
||||
//auto high = padded.resize_power2();
|
||||
//high.save(path_high);
|
||||
samp.second->save(path_high);
|
||||
auto thumb = padded.resize(64, 64);
|
||||
thumb.save(path_thumb);
|
||||
|
||||
@@ -136,9 +137,9 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
||||
void NodePanelStroke::update_controls()
|
||||
{
|
||||
const auto& b = Canvas::I->m_current_brush;
|
||||
m_tip_size->m_value.x = glm::pow(b->m_tip_size, 1.f/3.f);
|
||||
m_tip_spacing->m_value.x = glm::pow(b->m_tip_spacing, 1.f/2.f);
|
||||
m_tip_flow->m_value.x = glm::pow(b->m_tip_flow, 1.f/2.f);
|
||||
m_tip_size->m_value.x = m_curves[m_tip_size].to_slider(b->m_tip_size);
|
||||
m_tip_spacing->m_value.x = m_curves[m_tip_spacing].to_slider(b->m_tip_spacing);
|
||||
m_tip_flow->m_value.x = m_curves[m_tip_flow].to_slider(b->m_tip_flow);
|
||||
m_tip_opacity->m_value.x = b->m_tip_opacity;
|
||||
m_tip_angle->m_value.x = b->m_tip_angle;
|
||||
m_tip_angle_delay->m_value.x = b->m_tip_angle_delay;
|
||||
@@ -168,9 +169,9 @@ void NodePanelStroke::update_controls()
|
||||
m_tip_randflipx->checked = b->m_tip_randflipx;
|
||||
m_tip_randflipy->checked = b->m_tip_randflipy;
|
||||
|
||||
m_dual_size->m_value.x = glm::pow(b->m_dual_size, 1.f / 3.f);
|
||||
m_dual_spacing->m_value.x = glm::pow(b->m_dual_spacing, 1.f / 2.f);
|
||||
m_dual_flow->m_value.x = glm::pow(b->m_dual_flow, 1.f / 2.f);
|
||||
m_dual_size->m_value.x = m_curves[m_dual_size].to_slider(b->m_dual_size);
|
||||
m_dual_spacing->m_value.x = m_curves[m_dual_spacing].to_slider(b->m_dual_spacing);
|
||||
m_dual_flow->m_value.x = m_curves[m_dual_flow].to_slider(b->m_dual_flow);
|
||||
m_dual_scatter->m_value.x = b->m_dual_scatter;
|
||||
m_tip_aspect->m_value.x = b->m_tip_aspect;
|
||||
m_dual_opacity->m_value.x = b->m_dual_opacity;
|
||||
@@ -181,7 +182,7 @@ void NodePanelStroke::update_controls()
|
||||
m_pattern_flipx->checked = b->m_pattern_flipx;
|
||||
m_pattern_flipy->checked = b->m_pattern_flipy;
|
||||
m_pattern_rand_offset->checked = b->m_pattern_rand_offset;
|
||||
m_pattern_scale->m_value.x = b->m_pattern_scale;
|
||||
m_pattern_scale->m_value.x = m_curves[m_pattern_scale].to_slider(b->m_pattern_scale);
|
||||
m_pattern_brightness->m_value.x = b->m_pattern_brightness;
|
||||
m_pattern_contrast->m_value.x = b->m_pattern_contrast;
|
||||
m_pattern_depth->m_value.x = b->m_pattern_depth;
|
||||
@@ -247,8 +248,8 @@ void NodePanelStroke::init_controls()
|
||||
b->load_tip(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
|
||||
b->load_dual(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
|
||||
b->load_pattern(m_pattern_popup->get_texture_path(0), m_pattern_popup->get_thumb_path(0));
|
||||
b->m_tip_size = .1f;
|
||||
b->m_tip_flow = .5f;
|
||||
b->m_tip_size = 30;
|
||||
b->m_tip_flow = .9f;
|
||||
b->m_tip_spacing = .1f;
|
||||
b->m_tip_opacity = 1.f;
|
||||
Canvas::I->m_current_brush = b;
|
||||
@@ -470,14 +471,62 @@ void NodePanelStroke::init_controls()
|
||||
init_slider(m_pattern_contrast, "pattern-contrast", &Brush::m_pattern_contrast);
|
||||
init_slider(m_pattern_depth, "pattern-depth", &Brush::m_pattern_depth);
|
||||
|
||||
auto curve_cubic = [](float v) { return glm::pow(v, 3.f); };
|
||||
auto curve_quad = [](float v) { return glm::pow(v, 2.f); };
|
||||
m_curves[m_tip_size] = curve_cubic;
|
||||
m_curves[m_tip_spacing] = curve_quad;
|
||||
SliderCurve curve_cubic {
|
||||
[](float v) { return glm::pow(v, 3.f); },
|
||||
[](float v) { return glm::pow(v, 1.f / 3.f); },
|
||||
};
|
||||
SliderCurve curve_quad {
|
||||
[](float v) { return glm::pow(v, 2.f); },
|
||||
[](float v) { return glm::pow(v, 1.f / 2.f); },
|
||||
};
|
||||
SliderCurve curve_size1k_perc {
|
||||
[](float v) {
|
||||
float ret = 0;
|
||||
if (v > 0.00f) ret += glm::pow(glm::min(1.f, (v - 0.00f) / 0.50f), 2.f) * 1.f;
|
||||
if (v > 0.50f) ret += glm::min(1.f, (v - 0.50f) / 0.25f) * 2.f;
|
||||
if (v > 0.75f) ret += glm::min(1.f, (v - 0.75f) / 0.10f) * 4.f;
|
||||
if (v > 0.85f) ret += glm::min(1.f, (v - 0.85f) / 0.05f) * 5.f;
|
||||
if (v > 0.90f) ret += glm::min(1.f, (v - 0.90f) / 0.10f) * 10.f;
|
||||
return glm::max(.01f, ret);
|
||||
},
|
||||
[](float v) {
|
||||
float ret = 0;
|
||||
if (v > 0.f) ret += glm::pow(glm::min(1.f, (v - 0.f) / 1.f), 1.f / 2.f) * 0.50f;
|
||||
if (v > 1.f) ret += glm::min(1.f, (v - 1.f) / 2.f) * 0.25f;
|
||||
if (v > 2.f) ret += glm::min(1.f, (v - 2.f) / 4.f) * 0.10f;
|
||||
if (v > 4.f) ret += glm::min(1.f, (v - 4.f) / 5.f) * 0.05f;
|
||||
if (v > 5.f) ret += glm::min(1.f, (v - 5.f) / 10.f) * 0.10f;
|
||||
return ret;
|
||||
},
|
||||
};
|
||||
SliderCurve curve_size5k_pix {
|
||||
[](float v) {
|
||||
float ret = 0;
|
||||
if (v > 0.00f) ret += glm::pow(glm::min(1.f, (v - 0.00f) / 0.50f), 2.f) * 100.f;
|
||||
if (v > 0.50f) ret += glm::min(1.f, (v - 0.50f) / 0.25f) * 200.f;
|
||||
if (v > 0.75f) ret += glm::min(1.f, (v - 0.75f) / 0.10f) * 400.f;
|
||||
if (v > 0.85f) ret += glm::min(1.f, (v - 0.85f) / 0.05f) * 1000.f;
|
||||
if (v > 0.90f) ret += glm::min(1.f, (v - 0.90f) / 0.10f) * 5000.f;
|
||||
return glm::max(1.f, ret);
|
||||
},
|
||||
[](float v) {
|
||||
float ret = 0;
|
||||
if (v > 0.f) ret += glm::pow(glm::min(1.f, (v - 0.f) / 100.f), 1.f / 2.f) * 0.50f;
|
||||
if (v > 100.f) ret += glm::min(1.f, (v - 100.f) / 200.f) * 0.25f;
|
||||
if (v > 200.f) ret += glm::min(1.f, (v - 200.f) / 400.f) * 0.10f;
|
||||
if (v > 400.f) ret += glm::min(1.f, (v - 400.f) / 1000.f) * 0.05f;
|
||||
if (v > 1000.f) ret += glm::min(1.f, (v - 1000.f) / 5000.f) * 0.10f;
|
||||
return ret;
|
||||
},
|
||||
};
|
||||
|
||||
m_curves[m_tip_size] = curve_size5k_pix;
|
||||
m_curves[m_tip_spacing] = curve_size1k_perc;
|
||||
m_curves[m_tip_flow] = curve_quad;
|
||||
m_curves[m_dual_size] = curve_cubic;
|
||||
m_curves[m_dual_spacing] = curve_quad;
|
||||
m_curves[m_dual_size] = curve_size5k_pix;
|
||||
m_curves[m_dual_spacing] = curve_size1k_perc;
|
||||
m_curves[m_dual_flow] = curve_quad;
|
||||
m_curves[m_pattern_scale] = curve_size1k_perc;
|
||||
|
||||
m_tip_aspect_reset = find<NodeButtonCustom>("tip-aspect-reset");
|
||||
m_tip_aspect_reset->on_click = [this](Node*) {
|
||||
@@ -529,7 +578,7 @@ void NodePanelStroke::init_slider(NodeSliderH*& target, const char* id, float Br
|
||||
void NodePanelStroke::handle_slide(float Brush::* prop, Node* target, float value)
|
||||
{
|
||||
auto curve = m_curves.find((NodeSliderH*)target);
|
||||
Canvas::I->m_current_brush.get()->*prop = curve != m_curves.end() ? curve->second(value) : value;
|
||||
Canvas::I->m_current_brush.get()->*prop = curve != m_curves.end() ? curve->second.to_value(value) : value;
|
||||
m_preview->draw_stroke();
|
||||
if (on_stroke_change)
|
||||
on_stroke_change(this);
|
||||
|
||||
Reference in New Issue
Block a user