mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 15:30:00 +01:00
Improved draw texture by drawing a line between mouse cursor coordinates (instead of discrete points). This allows to use smaller size of pencil.
This commit is contained in:
@@ -21,26 +21,27 @@ uniform vec3 brush;
|
||||
uniform int option;
|
||||
uniform int effect;
|
||||
|
||||
float sdBox( in vec2 p, in float b)
|
||||
float sdBox( in vec2 v1, in vec2 v2, float r )
|
||||
{
|
||||
vec2 q = abs(p) - vec2(b);
|
||||
vec2 ba = v2 - v1;
|
||||
vec2 pa = -v1;
|
||||
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
vec2 q = abs(pa -h*ba) - vec2(r);
|
||||
float d = min( max(q.x, q.y), 0.0) + length(max(q,0.0));
|
||||
return 1.0 - abs(d) * step(d, 0.0);
|
||||
return 1.0 - abs( mix( 0.5, 1.0, d) ) * step(d, 0.0);
|
||||
}
|
||||
|
||||
float sdCircle( in vec2 p, in float b)
|
||||
float sdSegment( in vec2 v1, in vec2 v2, float r )
|
||||
{
|
||||
return ( length( p ) / b );
|
||||
vec2 ba = v2 - v1;
|
||||
vec2 pa = -v1;
|
||||
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
return length(pa-h*ba) / r;
|
||||
}
|
||||
|
||||
float sdElipse( in vec2 p, in float b)
|
||||
{
|
||||
return ( length( p ) / b );
|
||||
}
|
||||
|
||||
const mat3 KERNEL = mat3( 0.0625, 0.125, 0.0625,
|
||||
0.125, 0.25, 0.125,
|
||||
0.0625, 0.125, 0.0625);
|
||||
const mat3 KERNEL = mat3( 0.0555555, 0.111111, 0.0555555,
|
||||
0.111111, 0.333334, 0.111111,
|
||||
0.0555555, 0.111111, 0.0555555);
|
||||
|
||||
vec3 gaussian()
|
||||
{
|
||||
@@ -71,14 +72,15 @@ void main()
|
||||
// fragment coordinates
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
// adjust coordinates to match scaling area
|
||||
uv.x *= cursor.z ;
|
||||
uv.y *= cursor.w ;
|
||||
uv.x *= size.x ;
|
||||
uv.y *= size.y ;
|
||||
// cursor coordinates
|
||||
vec2 cursor = vec2(cursor.x, - cursor.y);
|
||||
vec2 cur = vec2(cursor.x, - cursor.y);
|
||||
vec2 cur_prev = vec2(cursor.z, - cursor.w);
|
||||
// use distance function relative to length brush.x (size), depending on brush.z (shape):
|
||||
// - brush.z = 0 : circle shape
|
||||
// - brush.z = 1 : square shape
|
||||
float d = (1.0 -brush.z) * sdCircle(cursor-uv, brush.x) + brush.z * sdBox(uv-cursor, brush.x);
|
||||
float d = (1.0 -brush.z) * sdSegment(cur_prev - uv, cur - uv, brush.x) + brush.z * sdBox(cur_prev - uv, cur - uv, brush.x);
|
||||
|
||||
// modify only the pixels inside the brush
|
||||
if( d < 1.0 )
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
@@ -450,6 +451,8 @@ std::pair<Node *, glm::vec2> TextureView::pick(glm::vec2 P)
|
||||
pick = { mask_cursor_circle_, P };
|
||||
// adapt grid to prepare grab action
|
||||
adaptGridToSource(current);
|
||||
// reset previous brush position
|
||||
previous_scene_brush_pos = glm::zero<glm::vec3>();
|
||||
return pick;
|
||||
}
|
||||
// special case for cropping the mask shape
|
||||
@@ -815,8 +818,8 @@ void TextureView::draw()
|
||||
ImGuiToolkit::ToolTip("Size");
|
||||
if (ImGui::BeginPopup("brush_size_popup", ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
int pixel_size_min = int(0.05 * edit_source_->frame()->height() );
|
||||
int pixel_size_max = int(2.0 * edit_source_->frame()->height() );
|
||||
int pixel_size_min = int(BRUSH_MIN_SIZE * edit_source_->frame()->height() );
|
||||
int pixel_size_max = int(BRUSH_MAX_SIZE * edit_source_->frame()->height() );
|
||||
int pixel_size = int(Settings::application.brush.x * edit_source_->frame()->height() );
|
||||
show_cursor_forced_ = true;
|
||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_DEFAULT);
|
||||
@@ -1106,16 +1109,26 @@ View::Cursor TextureView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pa
|
||||
// set brush coordinates (used in mouse over)
|
||||
scene_brush_pos = scene_to;
|
||||
|
||||
// no previous brush position : restart at same coordinates
|
||||
if ( glm::length( previous_scene_brush_pos ) < EPSILON)
|
||||
previous_scene_brush_pos = scene_brush_pos;
|
||||
|
||||
if ( pick.first == mask_cursor_circle_ ) {
|
||||
// snap prush coordinates if grid is active
|
||||
if (grid->active())
|
||||
scene_brush_pos = grid->snap(scene_brush_pos);
|
||||
// inform shader of a cursor action : coordinates and crop scaling
|
||||
edit_source_->maskShader()->size = edit_source_->mixingsurface_->scale_;
|
||||
|
||||
// inform shader of a cursor action : coordinates and crop scaling
|
||||
edit_source_->maskShader()->cursor = glm::vec4(scene_brush_pos.x - shift_crop_.x,
|
||||
scene_brush_pos.y - shift_crop_.y,
|
||||
edit_source_->mixingsurface_->scale_.x,
|
||||
edit_source_->mixingsurface_->scale_.y);
|
||||
previous_scene_brush_pos.x - shift_crop_.x,
|
||||
previous_scene_brush_pos.y - shift_crop_.y);
|
||||
edit_source_->touch(Source::SourceUpdate_Mask);
|
||||
|
||||
previous_scene_brush_pos = scene_brush_pos;
|
||||
|
||||
// action label
|
||||
info << MaskShader::mask_names[MaskShader::PAINT] << " changed";
|
||||
// cursor indication - no info, just cursor
|
||||
|
||||
@@ -72,6 +72,7 @@ private:
|
||||
|
||||
void adaptGridToSource(Source *s = nullptr, Node *picked = nullptr);
|
||||
glm::vec3 scene_brush_pos;
|
||||
glm::vec3 previous_scene_brush_pos;
|
||||
TranslationGrid *translation_grid_;
|
||||
RotationGrid *rotation_grid_;
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
#define APPEARANCE_DEFAULT_SCALE 2.f
|
||||
#define APPEARANCE_MIN_SCALE 0.4f
|
||||
#define APPEARANCE_MAX_SCALE 7.0f
|
||||
#define BRUSH_MIN_SIZE 0.05f
|
||||
#define BRUSH_MIN_SIZE 0.01f
|
||||
#define BRUSH_MAX_SIZE 2.f
|
||||
#define BRUSH_MIN_PRESS 0.005f
|
||||
#define BRUSH_MAX_PRESS 1.f
|
||||
|
||||
Reference in New Issue
Block a user