add abr color dynamics
This commit is contained in:
@@ -583,6 +583,9 @@
|
|||||||
<node height="20" justify="center">
|
<node height="20" justify="center">
|
||||||
<text text="Val"/>
|
<text text="Val"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node height="20" justify="center">
|
||||||
|
<text text="HSV Jitter"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node dir="col" grow="1" width="1">
|
<node dir="col" grow="1" width="1">
|
||||||
<node align="center" dir="row">
|
<node align="center" dir="row">
|
||||||
@@ -626,6 +629,10 @@
|
|||||||
<node height="20" pad="1" width="100%">
|
<node height="20" pad="1" width="100%">
|
||||||
<slider-h id="jitter-val"/>
|
<slider-h id="jitter-val"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node height="20" pad="1" width="100%" dir="row" align="center">
|
||||||
|
<checkbox width="20" height="19" id="jitter-hsv-eachsample"/>
|
||||||
|
<text text="each sample"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,15 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Color Dynamics
|
||||||
|
if (p->value<Boolean>("useColorDynamics"))
|
||||||
|
{
|
||||||
|
b->m_jitter_sat = p->value<UnitFloat>("Strt") * 0.01f;
|
||||||
|
b->m_jitter_hue = p->value<UnitFloat>("H ") * 0.01f;
|
||||||
|
b->m_jitter_val = p->value<UnitFloat>("Brgh") * 0.01f;
|
||||||
|
b->m_jitter_hsv_eachsample = p->value<Boolean>("colorDynamicsPerTip");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> modes = {
|
std::vector<std::string> modes = {
|
||||||
"normal", // normal (not in Photoshop)
|
"normal", // normal (not in Photoshop)
|
||||||
"Mltp", // multiply
|
"Mltp", // multiply
|
||||||
|
|||||||
@@ -150,7 +150,9 @@ void App::init_sidebar()
|
|||||||
stroke->set_size(value, true, true);
|
stroke->set_size(value, true, true);
|
||||||
};
|
};
|
||||||
quick->on_brush_change = [this](Node*, std::shared_ptr<Brush> b) {
|
quick->on_brush_change = [this](Node*, std::shared_ptr<Brush> b) {
|
||||||
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
||||||
*Canvas::I->m_current_brush = *b;
|
*Canvas::I->m_current_brush = *b;
|
||||||
|
Canvas::I->m_current_brush->m_tip_color = c;
|
||||||
brush_update();
|
brush_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -129,12 +129,6 @@ bool BrushMesh::create()
|
|||||||
}
|
}
|
||||||
StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float dir_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]
|
|
||||||
auto rnd_rad = [&] { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi]
|
|
||||||
auto rnd_vec = [&] { float rad = rnd_rad(); return glm::vec3(cosf(rad), sinf(rad), 0); }; // normalized direction vector
|
|
||||||
auto rnd_bneg = [&] { return prng() % 2 == 0 ? -1.f : 1.f; }; // -1 or 1
|
|
||||||
|
|
||||||
float size_dyn = m_brush->m_tip_size_pressure ? pressure : 1.f;
|
float size_dyn = m_brush->m_tip_size_pressure ? pressure : 1.f;
|
||||||
float flow_dyn = m_brush->m_tip_flow_pressure ? pressure : 1.f;
|
float flow_dyn = m_brush->m_tip_flow_pressure ? pressure : 1.f;
|
||||||
float opacity_dyn = m_brush->m_tip_opacity_pressure ? pressure : 1.f;
|
float opacity_dyn = m_brush->m_tip_opacity_pressure ? pressure : 1.f;
|
||||||
@@ -162,14 +156,24 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa
|
|||||||
s.pos = pos + (scatter_scale * rnd_vec() * m_brush->m_jitter_scatter * s.size * 0.5f); // 0.5 because PS scatters by half size
|
s.pos = pos + (scatter_scale * rnd_vec() * m_brush->m_jitter_scatter * s.size * 0.5f); // 0.5 because PS scatters by half size
|
||||||
s.flow = m_brush->m_tip_flow * (1.f - rnd_nor() * m_brush->m_jitter_flow) * flow_dyn;
|
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;
|
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);
|
|
||||||
hsv.x = glm::clamp(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush->m_tip_hue) + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue, 0.f, 1.f);
|
auto hsv = m_tip_color;
|
||||||
hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush->m_tip_sat) + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat, 0.f, 1.f);
|
float eachtip = m_brush->m_jitter_hsv_eachsample ? 1.f : 0.f;
|
||||||
hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush->m_tip_val) + (rnd_nor() - 0.5f) * m_brush->m_jitter_val, 0.f, 1.f);
|
hsv.x = glm::fract(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush->m_tip_hue) + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue * eachtip);
|
||||||
|
hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush->m_tip_sat) + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat * eachtip, 0.f, 1.f);
|
||||||
|
hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush->m_tip_val) + (rnd_nor() - 0.5f) * m_brush->m_jitter_val * eachtip, 0.f, 1.f);
|
||||||
m_hsv_jitter.add(hsv);
|
m_hsv_jitter.add(hsv);
|
||||||
s.col = convert_hsv2rgb(m_hsv_jitter.average());
|
s.col = convert_hsv2rgb(m_hsv_jitter.average());
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stroke::randomize_prng()
|
||||||
|
{
|
||||||
|
std::random_device rd;
|
||||||
|
prng.seed(rd());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<StrokeSample> Stroke::compute_samples()
|
std::vector<StrokeSample> Stroke::compute_samples()
|
||||||
{
|
{
|
||||||
if (m_keypoints.empty()) return {};
|
if (m_keypoints.empty()) return {};
|
||||||
@@ -321,6 +325,12 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
|
|||||||
float size = aspect_width * glm::min(m_brush->m_tip_scale.x, m_brush->m_tip_scale.y) * raw_size;
|
float size = aspect_width * glm::min(m_brush->m_tip_scale.x, m_brush->m_tip_scale.y) * raw_size;
|
||||||
m_step = glm::max(0.5f, m_brush->m_tip_spacing * size);
|
m_step = glm::max(0.5f, m_brush->m_tip_spacing * size);
|
||||||
|
|
||||||
|
auto hsv = convert_rgb2hsv(m_brush->m_tip_color);
|
||||||
|
hsv.x = glm::fract(hsv.x + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue);
|
||||||
|
hsv.y = glm::clamp(hsv.y + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat, 0.f, 1.f);
|
||||||
|
hsv.z = glm::clamp(hsv.z + (rnd_nor() - 0.5f) * m_brush->m_jitter_val, 0.f, 1.f);
|
||||||
|
m_tip_color = hsv;
|
||||||
|
|
||||||
m_direction.resize(std::max<int>(1, m_brush->m_tip_angle_smooth * 200.f / m_step));
|
m_direction.resize(std::max<int>(1, m_brush->m_tip_angle_smooth * 200.f / m_step));
|
||||||
prng.seed(0);
|
prng.seed(0);
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/brush.h
11
src/brush.h
@@ -54,6 +54,7 @@ public:
|
|||||||
float m_jitter_hue = 0;
|
float m_jitter_hue = 0;
|
||||||
float m_jitter_sat = 0;
|
float m_jitter_sat = 0;
|
||||||
float m_jitter_val = 0;
|
float m_jitter_val = 0;
|
||||||
|
bool m_jitter_hsv_eachsample = false;
|
||||||
float m_jitter_aspect = 0;
|
float m_jitter_aspect = 0;
|
||||||
bool m_jitter_aspect_bothaxis = false;
|
bool m_jitter_aspect_bothaxis = false;
|
||||||
int m_blend_mode = 0;
|
int m_blend_mode = 0;
|
||||||
@@ -172,6 +173,7 @@ public:
|
|||||||
float m_step = 0;
|
float m_step = 0;
|
||||||
float m_max_size = FLT_MAX;
|
float m_max_size = FLT_MAX;
|
||||||
bool m_filter_points = true;
|
bool m_filter_points = true;
|
||||||
|
glm::vec3 m_tip_color;
|
||||||
Camera m_camera;
|
Camera m_camera;
|
||||||
std::shared_ptr<Brush> m_brush;
|
std::shared_ptr<Brush> m_brush;
|
||||||
cbuffer<float> m_direction{ 1 };
|
cbuffer<float> m_direction{ 1 };
|
||||||
@@ -182,11 +184,18 @@ public:
|
|||||||
std::vector<std::pair<glm::vec3, float>> m_hold_points;
|
std::vector<std::pair<glm::vec3, float>> m_hold_points;
|
||||||
std::vector<StrokeSample> m_samples;
|
std::vector<StrokeSample> m_samples;
|
||||||
int m_last_kp;
|
int m_last_kp;
|
||||||
std::minstd_rand prng;
|
std::mt19937 prng;
|
||||||
void start(const std::shared_ptr<Brush>& brush);
|
void start(const std::shared_ptr<Brush>& brush);
|
||||||
void add_point(glm::vec3 pos, float pressure);
|
void add_point(glm::vec3 pos, float pressure);
|
||||||
void reset(bool clear_keypoints = false);
|
void reset(bool clear_keypoints = false);
|
||||||
bool has_sample();
|
bool has_sample();
|
||||||
std::vector<StrokeSample> compute_samples();
|
std::vector<StrokeSample> compute_samples();
|
||||||
StrokeSample randomize_sample(const glm::vec3& pos, float pressure, float curve_angle);
|
StrokeSample randomize_sample(const glm::vec3& pos, float pressure, float curve_angle);
|
||||||
|
|
||||||
|
void randomize_prng();
|
||||||
|
float rnd_nor() { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1]
|
||||||
|
float rnd_neg() { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1]
|
||||||
|
float rnd_rad() { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi]
|
||||||
|
glm::vec3 rnd_vec() { float rad = rnd_rad(); return glm::vec3(cosf(rad), sinf(rad), 0); }; // normalized direction vector
|
||||||
|
float rnd_bneg() { return prng() % 2 == 0 ? -1.f : 1.f; }; // -1 or 1
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -900,6 +900,7 @@ void Canvas::stroke_start(glm::vec3 point, float pressure)
|
|||||||
m_current_stroke = std::make_unique<Stroke>();
|
m_current_stroke = std::make_unique<Stroke>();
|
||||||
m_current_stroke->m_camera.rot = m_cam_rot;
|
m_current_stroke->m_camera.rot = m_cam_rot;
|
||||||
m_current_stroke->m_camera.fov = m_cam_fov;
|
m_current_stroke->m_camera.fov = m_cam_fov;
|
||||||
|
m_current_stroke->randomize_prng();
|
||||||
m_current_stroke->start(m_current_brush);
|
m_current_stroke->start(m_current_brush);
|
||||||
m_current_stroke->add_point(point, pressure);
|
m_current_stroke->add_point(point, pressure);
|
||||||
|
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const
|
|||||||
tip_color = glm::vec4(s.col, s.flow);
|
tip_color = glm::vec4(s.col, s.flow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::DrawOutline, glm::min(tip_scale.x, tip_scale.y) < 20 ? false : m_draw_outline);
|
ShaderManager::u_int(kShaderUniform::DrawOutline, glm::min(tip_scale.x, tip_scale.y) < 20 || m_resizing ? false : m_draw_outline);
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, tip_color);
|
ShaderManager::u_vec4(kShaderUniform::Col, tip_color);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP,
|
ShaderManager::u_mat4(kShaderUniform::MVP,
|
||||||
glm::scale(glm::vec3(1, -1, 1)) *
|
glm::scale(glm::vec3(1, -1, 1)) *
|
||||||
|
|||||||
26
src/main.cpp
26
src/main.cpp
@@ -34,7 +34,6 @@ std::thread hmd_renderer;
|
|||||||
std::thread renderer;
|
std::thread renderer;
|
||||||
int running = -1;
|
int running = -1;
|
||||||
std::mutex render_mutex;
|
std::mutex render_mutex;
|
||||||
std::mutex wnd_mutex;
|
|
||||||
std::condition_variable render_cv;
|
std::condition_variable render_cv;
|
||||||
|
|
||||||
int gl_count = 0;
|
int gl_count = 0;
|
||||||
@@ -687,12 +686,11 @@ int main(int argc, char** argv)
|
|||||||
static wchar_t title_fps[512];
|
static wchar_t title_fps[512];
|
||||||
swprintf_s(title_fps, L"%s - %d fps", window_title, frames);
|
swprintf_s(title_fps, L"%s - %d fps", window_title, frames);
|
||||||
|
|
||||||
// lock if
|
std::lock_guard<std::mutex> lock(main_task_mutex);
|
||||||
if (wnd_mutex.try_lock())
|
main_tasklist.emplace_back([=] {
|
||||||
{
|
|
||||||
SetWindowText(hWnd, title_fps);
|
SetWindowText(hWnd, title_fps);
|
||||||
wnd_mutex.unlock();
|
});
|
||||||
}
|
|
||||||
one_sec = 0;
|
one_sec = 0;
|
||||||
frames = 0;
|
frames = 0;
|
||||||
}
|
}
|
||||||
@@ -869,18 +867,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
running = 0;
|
running = 0;
|
||||||
render_cv.notify_all();
|
render_cv.notify_all();
|
||||||
|
if (renderer.joinable())
|
||||||
{
|
renderer.join();
|
||||||
// avoid deadlock
|
if (hmd_renderer.joinable())
|
||||||
// nobody should call windows API on this window at this time
|
hmd_renderer.join();
|
||||||
std::lock_guard<std::mutex> lock(wnd_mutex);
|
|
||||||
|
|
||||||
if (renderer.joinable())
|
|
||||||
renderer.join();
|
|
||||||
if (hmd_renderer.joinable())
|
|
||||||
hmd_renderer.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
App::I.terminate();
|
App::I.terminate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
14
src/node.cpp
14
src/node.cpp
@@ -94,7 +94,9 @@ kEventResult Node::on_event(Event* e)
|
|||||||
|
|
||||||
if (current_mouse_capture)
|
if (current_mouse_capture)
|
||||||
{
|
{
|
||||||
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus != current_mouse_capture)
|
if (e->m_cat == kEventCategory::MouseEvent &&
|
||||||
|
child_mouse_focus != current_mouse_capture &&
|
||||||
|
is_child(current_mouse_capture))
|
||||||
{
|
{
|
||||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||||
if (child_mouse_focus)
|
if (child_mouse_focus)
|
||||||
@@ -432,6 +434,16 @@ bool Node::is_child_recursive(Node* o) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Node::is_child(Node* o) const
|
||||||
|
{
|
||||||
|
for (const auto& c : m_children)
|
||||||
|
{
|
||||||
|
if (c.get() == o)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Node::mouse_capture()
|
void Node::mouse_capture()
|
||||||
{
|
{
|
||||||
auto& c = root()->current_mouse_capture;
|
auto& c = root()->current_mouse_capture;
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ public:
|
|||||||
// returns {origin, size} form
|
// returns {origin, size} form
|
||||||
glm::vec4 get_children_rect() const;
|
glm::vec4 get_children_rect() const;
|
||||||
bool is_child_recursive(Node* o) const;
|
bool is_child_recursive(Node* o) const;
|
||||||
|
bool is_child(Node* o) const;
|
||||||
void mouse_capture();
|
void mouse_capture();
|
||||||
void mouse_release();
|
void mouse_release();
|
||||||
void key_capture();
|
void key_capture();
|
||||||
|
|||||||
@@ -517,6 +517,7 @@ bool NodePanelBrushPreset::save()
|
|||||||
i.m_jitter_hue = b->m_jitter_hue;
|
i.m_jitter_hue = b->m_jitter_hue;
|
||||||
i.m_jitter_sat = b->m_jitter_sat;
|
i.m_jitter_sat = b->m_jitter_sat;
|
||||||
i.m_jitter_val = b->m_jitter_val;
|
i.m_jitter_val = b->m_jitter_val;
|
||||||
|
i.m_jitter_hsv_eachsample = b->m_jitter_hsv_eachsample;
|
||||||
i.m_jitter_aspect = b->m_jitter_aspect;
|
i.m_jitter_aspect = b->m_jitter_aspect;
|
||||||
i.m_jitter_aspect_bothaxis = b->m_jitter_aspect_bothaxis;
|
i.m_jitter_aspect_bothaxis = b->m_jitter_aspect_bothaxis;
|
||||||
i.m_blend_mode = b->m_blend_mode;
|
i.m_blend_mode = b->m_blend_mode;
|
||||||
@@ -624,6 +625,7 @@ bool NodePanelBrushPreset::restore()
|
|||||||
b->m_jitter_hue = i.m_jitter_hue;
|
b->m_jitter_hue = i.m_jitter_hue;
|
||||||
b->m_jitter_sat = i.m_jitter_sat;
|
b->m_jitter_sat = i.m_jitter_sat;
|
||||||
b->m_jitter_val = i.m_jitter_val;
|
b->m_jitter_val = i.m_jitter_val;
|
||||||
|
b->m_jitter_hsv_eachsample = i.m_jitter_hsv_eachsample;
|
||||||
b->m_jitter_aspect = i.m_jitter_aspect;
|
b->m_jitter_aspect = i.m_jitter_aspect;
|
||||||
b->m_jitter_aspect_bothaxis = i.m_jitter_aspect_bothaxis;
|
b->m_jitter_aspect_bothaxis = i.m_jitter_aspect_bothaxis;
|
||||||
b->m_blend_mode = i.m_blend_mode;
|
b->m_blend_mode = i.m_blend_mode;
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ class NodePanelBrushPreset : public Node
|
|||||||
float m_jitter_hue = 0;
|
float m_jitter_hue = 0;
|
||||||
float m_jitter_sat = 0;
|
float m_jitter_sat = 0;
|
||||||
float m_jitter_val = 0;
|
float m_jitter_val = 0;
|
||||||
|
bool m_jitter_hsv_eachsample = false;
|
||||||
float m_jitter_aspect = 0;
|
float m_jitter_aspect = 0;
|
||||||
bool m_jitter_aspect_bothaxis = false;
|
bool m_jitter_aspect_bothaxis = false;
|
||||||
int m_blend_mode = 0;
|
int m_blend_mode = 0;
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ void NodePanelStroke::update_controls()
|
|||||||
m_jitter_hue->m_value = b->m_jitter_hue;
|
m_jitter_hue->m_value = b->m_jitter_hue;
|
||||||
m_jitter_sat->m_value = b->m_jitter_sat;
|
m_jitter_sat->m_value = b->m_jitter_sat;
|
||||||
m_jitter_val->m_value = b->m_jitter_val;
|
m_jitter_val->m_value = b->m_jitter_val;
|
||||||
|
m_jitter_hsv_eachsample->checked = b->m_jitter_hsv_eachsample;
|
||||||
m_jitter_aspect->m_value = b->m_jitter_aspect;
|
m_jitter_aspect->m_value = b->m_jitter_aspect;
|
||||||
m_tip_angle_follow->checked = b->m_tip_angle_follow;
|
m_tip_angle_follow->checked = b->m_tip_angle_follow;
|
||||||
m_tip_angle_init->checked = b->m_tip_angle_init;
|
m_tip_angle_init->checked = b->m_tip_angle_init;
|
||||||
@@ -484,6 +485,7 @@ void NodePanelStroke::init_controls()
|
|||||||
init_checkbox(m_tip_size_pressure, "tip-size-pressure", &Brush::m_tip_size_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_jitter_scatter_bothaxis, "jitter-scatter-bothaxis", &Brush::m_jitter_scatter_bothaxis);
|
||||||
init_checkbox(m_jitter_aspect_bothaxis, "jitter-aspect-bothaxis", &Brush::m_jitter_aspect_bothaxis);
|
init_checkbox(m_jitter_aspect_bothaxis, "jitter-aspect-bothaxis", &Brush::m_jitter_aspect_bothaxis);
|
||||||
|
init_checkbox(m_jitter_hsv_eachsample, "jitter-hsv-eachsample", &Brush::m_jitter_hsv_eachsample);
|
||||||
|
|
||||||
init_checkbox(m_tip_invert, "tip-invert", &Brush::m_tip_invert);
|
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_flipx, "tip-flipx", &Brush::m_tip_flipx);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public:
|
|||||||
NodeSliderH* m_jitter_hue;
|
NodeSliderH* m_jitter_hue;
|
||||||
NodeSliderH* m_jitter_sat;
|
NodeSliderH* m_jitter_sat;
|
||||||
NodeSliderH* m_jitter_val;
|
NodeSliderH* m_jitter_val;
|
||||||
|
NodeCheckBox* m_jitter_hsv_eachsample;
|
||||||
NodeSliderH* m_jitter_aspect;
|
NodeSliderH* m_jitter_aspect;
|
||||||
NodeCheckBox* m_tip_angle_init;
|
NodeCheckBox* m_tip_angle_init;
|
||||||
NodeCheckBox* m_tip_angle_follow;
|
NodeCheckBox* m_tip_angle_follow;
|
||||||
|
|||||||
Reference in New Issue
Block a user