From 82905fcb61d59f0b183b7ea43a047ae85c5df560 Mon Sep 17 00:00:00 2001 From: hellerve Date: Mon, 5 Jun 2017 20:15:27 -0400 Subject: [PATCH] utils: added bezier shaping functions from flong --- utilities/flong.glsl | 129 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/utilities/flong.glsl b/utilities/flong.glsl index 935ef27..c161bc2 100644 --- a/utilities/flong.glsl +++ b/utilities/flong.glsl @@ -136,3 +136,132 @@ float normalized_log_sigmoid(float x, float a) { a = 1. / (1. + exp(0. -((x-.5)*a*2.))); return (a-b)/(c-b); } + +// bezier shaping + +float quad_bezier(float x, vec2 ab) { + float e = 0.00001; + float a = clamp(ab.x, 0., 1.); + float b = clamp(ab.y, 0., 1.); + if (a == 0.5) a += e; + + float om2a = 1. - 2.*a; + float t = (sqrt(a*a + om2a*x) - a)/om2a; + return (1.-2.*b)*(t*t) + (2.*b)*t; +} + + +// cubic bezier begin +float slope_from_t(float t, float A, float B, float C) { + return 1.0/(3.0*A*t*t + 2.0*B*t + C); +} + +float x_from_t(float t, float A, float B, float C, float D) { + return A*(t*t*t) + B*(t*t) + C*t + D; +} + +float y_from_t(float t, float E, float F, float G, float H) { + return E*(t*t*t) + F*(t*t) + G*t + H; +} + +float cubic_bezier(float x, vec2 a, vec2 b) { + float y0a = 0.00; + float x0a = 0.00; + float y1a = a.y; + float x1a = a.x; + float y2a = b.y; + float x2a = b.x; + float y3a = 1.00; + float x3a = 1.00; + + float A = x3a - 3.*x2a + 3.*x1a - x0a; + float B = 3.*x2a - 6.*x1a + 3.*x0a; + float C = 3.*x1a - 3.*x0a; + float D = x0a; + + float E = y3a - 3.*y2a + 3.*y1a - y0a; + float F = 3.*y2a - 6.*y1a + 3.*y0a; + float G = 3.*y1a - 3.*y0a; + float H = y0a; + + float currentt = x; + for (int i=0; i < 5; i++){ + float currentx = x_from_t(currentt, A, B, C, D); + float currentslope = slope_from_t(currentt, A, B, C); + currentt -= (currentx - x)*(currentslope); + currentt = clamp(currentt, 0., 1.); + } + + float y = y_from_t(currentt, E, F, G, H); + return y; +} +// cubic bezier end + +// cubic bezier through points (requires cubic bezier) begin +float b0 (float t){ + return (1.-t)*(1.-t)*(1.-t); +} +float b1 (float t){ + return 3.*t* (1.-t)*(1.-t); +} +float b2 (float t){ + return 3.*t*t* (1.-t); +} +float b3 (float t){ + return t*t*t; +} +float findx(float t, float x0, float x1, float x2, float x3) { + return x0*b0(t) + x1*b1(t) + x2*b2(t) + x3*b3(t); +} +float findy(float t, float y0, float y1, float y2, float y3) { + return y0*b0(t) + y1*b1(t) + y2*b2(t) + y3*b3(t); +} + +float cubic_bezier_through(float x, vec2 a, vec2 b) { + float y = 0.; + float e = 0.00001; + float minp = 0. + e; + float maxp = 1. - e; + a = clamp(a, minp, maxp); + b = clamp(b, minp, maxp); + + float x0 = 0.; + float y0 = 0.; + float x4 = a.x; + float y4 = a.y; + float x5 = b.x; + float y5 = b.y; + float x3 = 1.; + float y3 = 1.; + float x1,y1,x2,y2; + + // arbitrary but reasonable + float t1 = 0.3; + float t2 = 0.7; + + float b0t1 = b0(t1); + float b1t1 = b1(t1); + float b2t1 = b2(t1); + float b3t1 = b3(t1); + float b0t2 = b0(t2); + float b1t2 = b1(t2); + float b2t2 = b2(t2); + float b3t2 = b3(t2); + + float ccx = x4 - x0*b0t1 - x3*b3t1; + float ccy = y4 - y0*b0t1 - y3*b3t1; + float ffx = x5 - x0*b0t2 - x3*b3t2; + float ffy = y5 - y0*b0t2 - y3*b3t2; + + x2 = (ccx - (ffx*b1t1)/b1t2) / (b2t1 - (b1t1*b2t2)/b1t2); + y2 = (ccy - (ffy*b1t1)/b1t2) / (b2t1 - (b1t1*b2t2)/b1t2); + x1 = (ccx - x2*b2t1) / b1t1; + y1 = (ccy - y2*b2t1) / b1t1; + + x1 = clamp(x1, minp, maxp); + x2 = clamp(x2, minp, maxp); + + y = cubic_bezier(x, vec2(x1,y1), vec2(x2,y2)); + return clamp(y, 0., 1.); +} +// cubic bezier through points end