diff --git a/src/face-tracker-ptz.cpp b/src/face-tracker-ptz.cpp index 86abca8..dcc9d4b 100644 --- a/src/face-tracker-ptz.cpp +++ b/src/face-tracker-ptz.cpp @@ -1014,23 +1014,15 @@ static void draw_frame_info(struct face_tracker_ptz *s, bool landmark_only = fal if (draw_ref) { gs_effect_set_color(gs_effect_get_param_by_name(effect, "color"), 0xFFFFFF00); // amber - gs_render_start(false); - const float srwhr2 = sqrtf((float)s->known_width * s->known_height) * 0.5f; - const float rcx = (float)s->known_width*(0.5f + s->track_x); - const float rcy = (float)s->known_height*(0.5f - s->track_y); - gs_vertex2f(rcx-srwhr2*s->track_z, rcy); - gs_vertex2f(rcx+srwhr2*s->track_z, rcy); - gs_vertex2f(rcx, rcy-srwhr2*s->track_z); - gs_vertex2f(rcx, rcy+srwhr2*s->track_z); - gs_render_stop(GS_LINES); - - if (s->ftm->landmark_detection_data) { - gs_render_start(false); - float r = srwhr2 * s->track_z; - for (int i=0; i<=32; i++) - gs_vertex2f(rcx + r * sinf(M_PI * i / 8), rcy + r * cosf(M_PI * i / 8)); - gs_render_stop(GS_LINESTRIP); - } + render_reference_line r; + float srwh = sqrtf((float)s->known_width * s->known_height); + r.rcx = (float)s->known_width*(0.5f + s->track_x); + r.rcy = (float)s->known_height*(0.5f - s->track_y); + r.r = srwh * 0.5f * s->track_z; + r.has_landmark = !!s->ftm->landmark_detection_data; + r.e_deadband = s->e_deadband * r.gmwh; + r.e_nonlinear = s->e_nonlinear * r.gmwh; + r.render(); } } } diff --git a/src/face-tracker.cpp b/src/face-tracker.cpp index 68393b1..56282a5 100644 --- a/src/face-tracker.cpp +++ b/src/face-tracker.cpp @@ -843,32 +843,16 @@ static inline void draw_frame_info(struct face_tracker_filter *s, bool debug_not } if (debug_notrack && draw_ref) { gs_effect_set_color(gs_effect_get_param_by_name(effect, "color"), 0xFFFFFF00); // amber + const float srwh = sqrtf((float)s->known_width * s->known_height); const rectf_s &r = s->ftm->crop_cur; - gs_render_start(false); - gs_vertex2f(r.x0, r.y0); - gs_vertex2f(r.x0, r.y1); - gs_vertex2f(r.x0, r.y1); - gs_vertex2f(r.x1, r.y1); - gs_vertex2f(r.x1, r.y1); - gs_vertex2f(r.x1, r.y0); - gs_vertex2f(r.x1, r.y0); - gs_vertex2f(r.x0, r.y0); - const float srwhr2 = sqrtf((r.x1-r.x0) * (r.y1-r.y0)) * 0.5f; - const float rcx = (r.x0+r.x1)*0.5f + (r.x1-r.x0)*s->track_x; - const float rcy = (r.y0+r.y1)*0.5f - (r.y1-r.y0)*s->track_y; - gs_vertex2f(rcx-srwhr2*s->track_z, rcy); - gs_vertex2f(rcx+srwhr2*s->track_z, rcy); - gs_vertex2f(rcx, rcy-srwhr2*s->track_z); - gs_vertex2f(rcx, rcy+srwhr2*s->track_z); - gs_render_stop(GS_LINES); - - if (s->ftm->landmark_detection_data) { - gs_render_start(false); - float r = srwhr2 * s->track_z; - for (int i=0; i<=32; i++) - gs_vertex2f(rcx + r * sinf(M_PI * i / 8), rcy + r * cosf(M_PI * i / 8)); - gs_render_stop(GS_LINESTRIP); - } + render_reference_line render; + render.rcx = (r.x0+r.x1)*0.5f + (r.x1-r.x0)*s->track_x; + render.rcy = (r.y0+r.y1)*0.5f - (r.y1-r.y0)*s->track_y; + render.r = sqrtf((r.x1-r.x0) * (r.y1-r.y0)) * 0.5f * s->track_z; + render.has_landmark = !!s->ftm->landmark_detection_data; + render.e_deadband = s->e_deadband * srwh; + render.e_nonlinear = s->e_nonlinear * srwh; + render.render(); } } diff --git a/src/helper.cpp b/src/helper.cpp index 16e35d7..bfb4ae3 100644 --- a/src/helper.cpp +++ b/src/helper.cpp @@ -136,6 +136,62 @@ void draw_landmark(const std::vector &landmark) gs_render_stop(GS_LINES); } +static void render_circle(float cx, float cy, float r) +{ + gs_render_start(false); + int n = r > 2.0f ? (int)ceilf(M_PI * 2.0f * r / sqrtf(2.0f * r - 1.0f)) : 8; + float d = M_PI * 4.0f / n; + for (int i = 0; i <= n; i++) + gs_vertex2f(cx + r * sinf(d * i), cy + r * cosf(d * i)); + gs_render_stop(GS_LINESTRIP); +} + +void render_reference_line::render() const +{ + gs_render_start(false); + gs_vertex2f(rcx-r, rcy); + gs_vertex2f(rcx+r, rcy); + gs_vertex2f(rcx, rcy-r); + gs_vertex2f(rcx, rcy+r); + + if (e_deadband.v[0] > 1e-4f) { + float dx = e_deadband.v[0]; + gs_vertex2f(rcx - dx, rcy - r * 0.5f); + gs_vertex2f(rcx - dx, rcy + r * 0.5f); + gs_vertex2f(rcx + dx, rcy - r * 0.5f); + gs_vertex2f(rcx + dx, rcy + r * 0.5f); + } + + if (e_deadband.v[1] > 1e-4f) { + float dy = e_deadband.v[1]; + gs_vertex2f(rcx - r * 0.5f, rcy - dy); + gs_vertex2f(rcx + r * 0.5f, rcy - dy); + gs_vertex2f(rcx - r * 0.5f, rcy + dy); + gs_vertex2f(rcx + r * 0.5f, rcy + dy); + } + + if (e_nonlinear.v[0] > 1e-4f) { + float dx = (e_nonlinear.v[0] + e_deadband.v[0]); + gs_vertex2f(rcx - dx, rcy - r * 0.25f); + gs_vertex2f(rcx - dx, rcy + r * 0.25f); + gs_vertex2f(rcx + dx, rcy - r * 0.25f); + gs_vertex2f(rcx + dx, rcy + r * 0.25f); + } + + if (e_nonlinear.v[1] > 1e-4f) { + float dy = (e_nonlinear.v[1] + e_deadband.v[1]); + gs_vertex2f(rcx - r * 0.25f, rcy - dy); + gs_vertex2f(rcx + r * 0.25f, rcy - dy); + gs_vertex2f(rcx - r * 0.25f, rcy + dy); + gs_vertex2f(rcx + r * 0.25f, rcy + dy); + } + + gs_render_stop(GS_LINES); + + if (has_landmark) + render_circle(rcx, rcy, r); +} + void debug_data_open(FILE **dest, char **last_name, obs_data_t *settings, const char *name) { const char *debug_data = obs_data_get_string(settings, name); diff --git a/src/helper.hpp b/src/helper.hpp index 0e48b1e..15b83ac 100644 --- a/src/helper.hpp +++ b/src/helper.hpp @@ -37,6 +37,7 @@ struct f3 { float v[3]; + f3 () {} f3 (const f3 &a) {*this=a;} f3 (float a, float b, float c) { v[0]=a; v[1]=b; v[2]=c; } f3 (const rect_s &a) { v[0]=(float)(a.x0+a.x1)*0.5f; v[1]=(float)(a.y0+a.y1)*0.5f; v[2]=sqrtf((float)(a.x1-a.x0)*(float)(a.y1-a.y0)); } @@ -103,6 +104,18 @@ void draw_landmark(const std::vector &landmark); float landmark_area(const std::vector &landmark); pointf_s landmark_center(const std::vector &landmark); +struct render_reference_line +{ + float rcx, rcy; + float gmwh; // geometric mean of width and height + float r; + f3 e_deadband; + f3 e_nonlinear; + bool has_landmark; + + void render() const; +}; + inline double from_dB(double x) { return exp(x * (M_LN10/20));