Compare commits

...

2 Commits

6 changed files with 61 additions and 87 deletions

View File

@@ -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 )

View File

@@ -426,66 +426,24 @@ void InputMappingWindow::SliderParametersCallback(SourceCallback *callback, cons
bool bd = edited->bidirectional();
if ( ImGuiToolkit::IconToggle(2, 13, 3, 13, &bd, press_tooltip ) )
edited->setBidirectional(bd);
// get value (gst time) and convert to hh mm s.ms
guint64 ms = GST_TIME_AS_MSECONDS(edited->value());
guint64 hh = ms / 3600000;
guint64 mm = (ms % 3600000) / 60000;
ms -= (hh * 3600000 + mm * 60000);
float sec = (float) (ms) / 1000.f;
// filtering for reading MM:SS.MS text entry
static bool valid = true;
static std::regex RegExTime("([0-9]+\\:)?([0-9]+\\:)?([0-5][0-9]|[0-9])((\\.|\\,)[0-9]+)?");
struct TextFilters { static int FilterTime(ImGuiInputTextCallbackData* data) {
if (data->EventChar < 256 && strchr("0123456789.,:", (char)data->EventChar)) return 0; return 1; }
};
char buf6[64] = "";
snprintf(buf6, 64, "%lu:%lu:%.2f", (unsigned long) hh, (unsigned long) mm, sec );
// Text input field for MM:SS:MS seek target time
ImGui::SetNextItemWidth(right_align);
ImGui::SameLine(0, IMGUI_SAME_LINE / 2);
ImGui::PushStyleColor(ImGuiCol_Text,
ImVec4(1.0f, valid ? 1.0f : 0.2f, valid ? 1.0f : 0.2f, 1.f));
ImGui::InputText("##CALLBACK_SEEK",
buf6,
64,
ImGuiInputTextFlags_CallbackCharFilter,
TextFilters::FilterTime);
valid = std::regex_match(buf6, RegExTime);
if (ImGui::IsItemDeactivatedAfterEdit()) {
if (valid) {
ms = 0;
sec = 0.f;
// user confirmed the entry and the input is valid
// split the "HH:MM:SS.ms" string in HH MM SS.ms
std::string time(buf6);
std::size_t found = time.find_last_of(':');
// read the right part SS.ms as a value
if (std::string::npos != found && BaseToolkit::is_a_value(time.substr(found + 1), &sec)) {
ms = (glm::uint64)(sec * 1000.f);
// read right part MM as a number
time = time.substr(0, found);
found = time.find_last_of(':');
int min = 0;
if (std::string::npos != found && BaseToolkit::is_a_number(time.substr(found + 1), &min)) {
ms += 60000 * (glm::uint64) min;
// read right part HH as a number
time = time.substr(0, found);
int hour = 0;
if (std::string::npos != found && BaseToolkit::is_a_number(time, &hour)) {
ms += 3600000 * (glm::uint64) hour;
}
}
}
// set time in mili seconds
edited->setValue( GST_MSECOND * ms );
}
// force to test validity next frame
valid = false;
guint64 duration = GST_SECOND * 1000;
if (Source * const* v = std::get_if<Source *>(&target)) {
MediaSource *ms = dynamic_cast<MediaSource*>(*v);
if (ms)
duration = ms->mediaplayer()->timeline()->duration();
}
static bool valid = false;
guint64 target_time = edited->value();
if ( ImGuiToolkit::InputTime("##CALLBACK_SEEK", &target_time, duration, &valid) ){
if (valid)
edited->setValue( target_time );
}
ImGui::PopStyleColor();
ImGui::SameLine(0, IMGUI_SAME_LINE / 3);
ImGuiToolkit::Indication("Target time (HH:MM:SS.MS) to set where to jump to in a video source.", 15, 7);

View File

@@ -406,6 +406,15 @@ Source::Source(uint64_t id) : SourceCore(), id_(id), ready_(false), symbol_(null
Source::~Source()
{
// clear and delete callbacks
access_callbacks_.lock();
for (auto iter=update_callbacks_.begin(); iter != update_callbacks_.end(); ) {
SourceCallback *callback = *iter;
iter = update_callbacks_.erase(iter);
delete callback;
}
access_callbacks_.unlock();
// inform links that they lost their target
while ( !links_.empty() )
links_.front()->disconnect();
@@ -431,15 +440,6 @@ Source::~Source()
overlays_.clear();
frames_.clear();
handles_.clear();
// clear and delete callbacks
access_callbacks_.lock();
for (auto iter=update_callbacks_.begin(); iter != update_callbacks_.end(); ) {
SourceCallback *callback = *iter;
iter = update_callbacks_.erase(iter);
delete callback;
}
access_callbacks_.unlock();
}
void Source::setName (const std::string &name)

View File

@@ -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

View File

@@ -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_;
};

View File

@@ -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