From 5329147d58abc75b70cabab8e784bb9bf262cf82 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 7 Mar 2019 00:53:45 +0100 Subject: [PATCH] add abr color dynamics --- data/layout.xml | 7 +++++++ src/abr.cpp | 9 +++++++++ src/app_layout.cpp | 2 ++ src/brush.cpp | 30 ++++++++++++++++++++---------- src/brush.h | 11 ++++++++++- src/canvas.cpp | 1 + src/canvas_modes.cpp | 2 +- src/main.cpp | 26 ++++++++------------------ src/node.cpp | 14 +++++++++++++- src/node.h | 1 + src/node_panel_brush.cpp | 2 ++ src/node_panel_brush.h | 1 + src/node_panel_stroke.cpp | 2 ++ src/node_panel_stroke.h | 1 + 14 files changed, 78 insertions(+), 31 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 1ff969b..1ccd02b 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -583,6 +583,9 @@ + + + @@ -626,6 +629,10 @@ + + + + diff --git a/src/abr.cpp b/src/abr.cpp index dbc0d5a..b066a9b 100644 --- a/src/abr.cpp +++ b/src/abr.cpp @@ -225,6 +225,15 @@ std::vector> ABR::compute_brushes(const std::string& path } + // Color Dynamics + if (p->value("useColorDynamics")) + { + b->m_jitter_sat = p->value("Strt") * 0.01f; + b->m_jitter_hue = p->value("H ") * 0.01f; + b->m_jitter_val = p->value("Brgh") * 0.01f; + b->m_jitter_hsv_eachsample = p->value("colorDynamicsPerTip"); + } + std::vector modes = { "normal", // normal (not in Photoshop) "Mltp", // multiply diff --git a/src/app_layout.cpp b/src/app_layout.cpp index aa5e93c..a08c3d6 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -150,7 +150,9 @@ void App::init_sidebar() stroke->set_size(value, true, true); }; quick->on_brush_change = [this](Node*, std::shared_ptr b) { + auto c = Canvas::I->m_current_brush->m_tip_color; *Canvas::I->m_current_brush = *b; + Canvas::I->m_current_brush->m_tip_color = c; brush_update(); }; diff --git a/src/brush.cpp b/src/brush.cpp index be52ec8..495be16 100644 --- a/src/brush.cpp +++ b/src/brush.cpp @@ -129,12 +129,6 @@ bool BrushMesh::create() } 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 flow_dyn = m_brush->m_tip_flow_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.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); - 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); - 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); - 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); + + auto hsv = m_tip_color; + float eachtip = m_brush->m_jitter_hsv_eachsample ? 1.f : 0.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); s.col = convert_hsv2rgb(m_hsv_jitter.average()); + return s; } + +void Stroke::randomize_prng() +{ + std::random_device rd; + prng.seed(rd()); +} + std::vector Stroke::compute_samples() { if (m_keypoints.empty()) return {}; @@ -320,6 +324,12 @@ void Stroke::start(const std::shared_ptr& brush) float raw_size = glm::clamp(m_brush->m_tip_size / glm::tan(glm::radians(m_camera.fov * 0.5f)), 1.f, m_max_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); + + 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(1, m_brush->m_tip_angle_smooth * 200.f / m_step)); prng.seed(0); diff --git a/src/brush.h b/src/brush.h index 6c895f9..d45f77c 100644 --- a/src/brush.h +++ b/src/brush.h @@ -54,6 +54,7 @@ public: float m_jitter_hue = 0; float m_jitter_sat = 0; float m_jitter_val = 0; + bool m_jitter_hsv_eachsample = false; float m_jitter_aspect = 0; bool m_jitter_aspect_bothaxis = false; int m_blend_mode = 0; @@ -172,6 +173,7 @@ public: float m_step = 0; float m_max_size = FLT_MAX; bool m_filter_points = true; + glm::vec3 m_tip_color; Camera m_camera; std::shared_ptr m_brush; cbuffer m_direction{ 1 }; @@ -182,11 +184,18 @@ public: std::vector> m_hold_points; std::vector m_samples; int m_last_kp; - std::minstd_rand prng; + std::mt19937 prng; void start(const std::shared_ptr& brush); void add_point(glm::vec3 pos, float pressure); void reset(bool clear_keypoints = false); bool has_sample(); std::vector compute_samples(); 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 }; diff --git a/src/canvas.cpp b/src/canvas.cpp index 2f69360..a4b6749 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -900,6 +900,7 @@ void Canvas::stroke_start(glm::vec3 point, float pressure) m_current_stroke = std::make_unique(); m_current_stroke->m_camera.rot = m_cam_rot; m_current_stroke->m_camera.fov = m_cam_fov; + m_current_stroke->randomize_prng(); m_current_stroke->start(m_current_brush); m_current_stroke->add_point(point, pressure); diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index aa3abb3..bbc1c85 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -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); } } - 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_mat4(kShaderUniform::MVP, glm::scale(glm::vec3(1, -1, 1)) * diff --git a/src/main.cpp b/src/main.cpp index 30546b1..98fe5b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,6 @@ std::thread hmd_renderer; std::thread renderer; int running = -1; std::mutex render_mutex; -std::mutex wnd_mutex; std::condition_variable render_cv; int gl_count = 0; @@ -687,12 +686,11 @@ int main(int argc, char** argv) static wchar_t title_fps[512]; swprintf_s(title_fps, L"%s - %d fps", window_title, frames); - // lock if - if (wnd_mutex.try_lock()) - { + std::lock_guard lock(main_task_mutex); + main_tasklist.emplace_back([=] { SetWindowText(hWnd, title_fps); - wnd_mutex.unlock(); - } + }); + one_sec = 0; frames = 0; } @@ -869,18 +867,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { running = 0; render_cv.notify_all(); - - { - // avoid deadlock - // nobody should call windows API on this window at this time - std::lock_guard lock(wnd_mutex); - - if (renderer.joinable()) - renderer.join(); - if (hmd_renderer.joinable()) - hmd_renderer.join(); - } - + if (renderer.joinable()) + renderer.join(); + if (hmd_renderer.joinable()) + hmd_renderer.join(); App::I.terminate(); } break; diff --git a/src/node.cpp b/src/node.cpp index 6dfa25c..61a84b9 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -94,7 +94,9 @@ kEventResult Node::on_event(Event* e) 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(e); if (child_mouse_focus) @@ -432,6 +434,16 @@ bool Node::is_child_recursive(Node* o) const 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() { auto& c = root()->current_mouse_capture; diff --git a/src/node.h b/src/node.h index dcd260e..84f4f67 100644 --- a/src/node.h +++ b/src/node.h @@ -259,6 +259,7 @@ public: // returns {origin, size} form glm::vec4 get_children_rect() const; bool is_child_recursive(Node* o) const; + bool is_child(Node* o) const; void mouse_capture(); void mouse_release(); void key_capture(); diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 8b6f90e..166a205 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -517,6 +517,7 @@ bool NodePanelBrushPreset::save() i.m_jitter_hue = b->m_jitter_hue; i.m_jitter_sat = b->m_jitter_sat; 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_bothaxis = b->m_jitter_aspect_bothaxis; 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_sat = i.m_jitter_sat; 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_bothaxis = i.m_jitter_aspect_bothaxis; b->m_blend_mode = i.m_blend_mode; diff --git a/src/node_panel_brush.h b/src/node_panel_brush.h index 306c86f..2e8ba24 100644 --- a/src/node_panel_brush.h +++ b/src/node_panel_brush.h @@ -137,6 +137,7 @@ class NodePanelBrushPreset : public Node float m_jitter_hue = 0; float m_jitter_sat = 0; float m_jitter_val = 0; + bool m_jitter_hsv_eachsample = false; float m_jitter_aspect = 0; bool m_jitter_aspect_bothaxis = false; int m_blend_mode = 0; diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index 4c7e2cb..b7e6b28 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -163,6 +163,7 @@ void NodePanelStroke::update_controls() m_jitter_hue->m_value = b->m_jitter_hue; m_jitter_sat->m_value = b->m_jitter_sat; 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_tip_angle_follow->checked = b->m_tip_angle_follow; 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_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_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_flipx, "tip-flipx", &Brush::m_tip_flipx); diff --git a/src/node_panel_stroke.h b/src/node_panel_stroke.h index ef43570..00534a5 100644 --- a/src/node_panel_stroke.h +++ b/src/node_panel_stroke.h @@ -34,6 +34,7 @@ public: NodeSliderH* m_jitter_hue; NodeSliderH* m_jitter_sat; NodeSliderH* m_jitter_val; + NodeCheckBox* m_jitter_hsv_eachsample; NodeSliderH* m_jitter_aspect; NodeCheckBox* m_tip_angle_init; NodeCheckBox* m_tip_angle_follow;