#pragma once\r
\r
#include <boost/assign/list_of.hpp>\r
+#include <boost/regex.hpp>\r
+#include <boost/lexical_cast.hpp>\r
+\r
#include <unordered_map>\r
#include <string>\r
#include <locale>\r
#include <functional>\r
+#include <vector>\r
\r
namespace caspar {\r
\r
static const double PI = std::atan(1.0)*4.0;\r
static const double H_PI = std::atan(1.0)*2.0;\r
\r
-inline double ease_none (double t, double b, double c, double d) \r
+inline double ease_none (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*t/d + b;\r
}\r
\r
-inline double ease_in_quad (double t, double b, double c, double d) \r
+inline double ease_in_quad (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*(t/=d)*t + b;\r
}\r
\r
-inline double ease_out_quad (double t, double b, double c, double d) \r
+inline double ease_out_quad (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return -c *(t/=d)*(t-2) + b;\r
} \r
\r
-inline double ease_in_out_quad (double t, double b, double c, double d)\r
+inline double ease_in_out_quad (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
if ((t/=d/2) < 1) \r
return c/2*t*t + b;\r
return -c/2 * ((--t)*(t-2) - 1) + b;\r
} \r
\r
-inline double ease_out_in_quad (double t, double b, double c, double d)\r
+inline double ease_out_in_quad (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
if (t < d/2) \r
- return ease_out_quad (t*2, b, c/2, d);\r
+ return ease_out_quad (t*2, b, c/2, d, params);\r
\r
- return ease_in_quad((t*2)-d, b+c/2, c/2, d);\r
+ return ease_in_quad((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-inline double ease_in_cubic (double t, double b, double c, double d) \r
+inline double ease_in_cubic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*(t/=d)*t*t + b;\r
} \r
\r
-inline double ease_out_cubic (double t, double b, double c, double d) \r
+inline double ease_out_cubic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*((t=t/d-1)*t*t + 1) + b;\r
}\r
\r
-inline double ease_in_out_cubic (double t, double b, double c, double d) \r
+inline double ease_in_out_cubic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if ((t/=d/2) < 1) \r
return c/2*t*t*t + b;\r
return c/2*((t-=2)*t*t + 2) + b;\r
}\r
\r
-inline double ease_out_in_cubic (double t, double b, double c, double d) \r
+inline double ease_out_in_cubic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
- if (t < d/2) return ease_out_cubic (t*2, b, c/2, d);\r
- return ease_in_cubic((t*2)-d, b+c/2, c/2, d);\r
+ if (t < d/2) return ease_out_cubic (t*2, b, c/2, d, params);\r
+ return ease_in_cubic((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-inline double ease_in_quart (double t, double b, double c, double d) \r
+inline double ease_in_quart (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*(t/=d)*t*t*t + b;\r
}\r
\r
-inline double ease_out_quart (double t, double b, double c, double d) \r
+inline double ease_out_quart (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return -c * ((t=t/d-1)*t*t*t - 1) + b;\r
} \r
\r
-inline double ease_in_out_quart (double t, double b, double c, double d) \r
+inline double ease_in_out_quart (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if ((t/=d/2) < 1)\r
return c/2*t*t*t*t + b;\r
return -c/2 * ((t-=2)*t*t*t - 2) + b;\r
} \r
\r
-inline double ease_out_in_quart (double t, double b, double c, double d) \r
+inline double ease_out_in_quart (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if (t < d/2)\r
- return ease_out_quart (t*2, b, c/2, d);\r
+ return ease_out_quart (t*2, b, c/2, d, params);\r
\r
- return ease_in_quart((t*2)-d, b+c/2, c/2, d);\r
+ return ease_in_quart((t*2)-d, b+c/2, c/2, d, params);\r
} \r
\r
-inline double ease_in_quint (double t, double b, double c, double d) \r
+inline double ease_in_quint (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*(t/=d)*t*t*t*t + b;\r
}\r
\r
-inline double ease_out_quint (double t, double b, double c, double d) \r
+inline double ease_out_quint (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c*((t=t/d-1)*t*t*t*t + 1) + b;\r
}\r
\r
-inline double ease_in_out_quint (double t, double b, double c, double d) \r
+inline double ease_in_out_quint (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if ((t/=d/2) < 1) \r
return c/2*t*t*t*t*t + b;\r
return c/2*((t-=2)*t*t*t*t + 2) + b;\r
}\r
\r
-inline double ease_out_in_quint (double t, double b, double c, double d) \r
+inline double ease_out_in_quint (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if (t < d/2) \r
- return ease_out_quint (t*2, b, c/2, d);\r
+ return ease_out_quint (t*2, b, c/2, d, params);\r
\r
- return ease_in_quint((t*2)-d, b+c/2, c/2, d);\r
+ return ease_in_quint((t*2)-d, b+c/2, c/2, d, params);\r
} \r
\r
-inline double ease_in_sine (double t, double b, double c, double d) \r
+inline double ease_in_sine (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return -c * std::cos(t/d * (PI/2)) + c + b;\r
} \r
\r
-inline double ease_out_sine (double t, double b, double c, double d) \r
+inline double ease_out_sine (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c * std::sin(t/d * (PI/2)) + b;\r
} \r
\r
-inline double ease_in_out_sine (double t, double b, double c, double d) \r
+inline double ease_in_out_sine (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return -c/2 * (std::cos(PI*t/d) - 1) + b;\r
} \r
\r
-inline double ease_out_in_sine (double t, double b, double c, double d)\r
+inline double ease_out_in_sine (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
if (t < d/2) \r
- return ease_out_sine (t*2, b, c/2, d);\r
+ return ease_out_sine (t*2, b, c/2, d, params);\r
\r
- return ease_in_sine((t*2)-d, b+c/2, c/2, d);\r
+ return ease_in_sine((t*2)-d, b+c/2, c/2, d, params);\r
} \r
\r
-inline double ease_in_expo (double t, double b, double c, double d) \r
+inline double ease_in_expo (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return (t==0) ? b : c * std::pow(2, 10 * (t/d - 1)) + b - c * 0.001;\r
} \r
\r
-inline double ease_out_expo (double t, double b, double c, double d) \r
+inline double ease_out_expo (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return (t==d) ? b+c : c * 1.001 * (-std::pow(2, -10 * t/d) + 1) + b;\r
}\r
\r
-inline double ease_in_out_expo (double t, double b, double c, double d) \r
+inline double ease_in_out_expo (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if (t==0) \r
return b;\r
return c/2 * 1.0005 * (-std::pow(2, -10 * --t) + 2) + b;\r
}\r
\r
-inline double ease_out_in_expo (double t, double b, double c, double d) {\r
+inline double ease_out_in_expo (double t, double b, double c, double d, const std::vector<double>& params) \r
+{\r
if (t < d/2) \r
- return ease_out_expo (t*2, b, c/2, d);\r
+ return ease_out_expo (t*2, b, c/2, d, params);\r
\r
- return ease_in_expo((t*2)-d, b+c/2, c/2, d);\r
+ return ease_in_expo((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-inline double ease_in_circ (double t, double b, double c, double d) \r
+inline double ease_in_circ (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return -c * (std::sqrt(1 - (t/=d)*t) - 1) + b;\r
}\r
\r
-inline double ease_out_circ (double t, double b, double c, double d) \r
+inline double ease_out_circ (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
return c * std::sqrt(1 - (t=t/d-1)*t) + b;\r
}\r
\r
-inline double ease_in_out_circ (double t, double b, double c, double d) \r
+inline double ease_in_out_circ (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if ((t/=d/2) < 1) \r
return -c/2 * (std::sqrt(1 - t*t) - 1) + b;\r
return c/2 * (std::sqrt(1 - (t-=2)*t) + 1) + b;\r
}\r
\r
-inline double ease_out_in_circ (double t, double b, double c, double d) \r
+inline double ease_out_in_circ (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
- if (t < d/2) return ease_out_circ(t*2, b, c/2, d);\r
- return ease_in_circ((t*2)-d, b+c/2, c/2, d);\r
+ if (t < d/2) return ease_out_circ(t*2, b, c/2, d, params);\r
+ return ease_in_circ((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-inline double ease_in_elastic (double t, double b, double c, double d)\r
+inline double ease_in_elastic (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
if (t==0) return b;\r
if ((t/=d)==1) return b+c;\r
//var p:Number = !Boolean(p_params) || isNaN(p_params.period) ? d*.3 : p_params.period;\r
//var s:Number;\r
//var a:Number = !Boolean(p_params) || isNaN(p_params.amplitude) ? 0 : p_params.amplitude;\r
- double p = d*0.3;\r
+ double p = params.size() > 0 ? params[0] : d*0.3;\r
double s;\r
- double a = 0.0;\r
+ double a = params.size() > 1 ? params[1] : 0.0;\r
if (a == 0.0 || a < std::abs(c)) \r
{\r
a = c;\r
return -(a*std::pow(2,10*(t-=1)) * std::sin( (t*d-s)*(2*PI)/p )) + b;\r
}\r
\r
-inline double ease_out_elastic (double t, double b, double c, double d) \r
+inline double ease_out_elastic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if (t==0) \r
return b;\r
//var p:Number = !Boolean(p_params) || isNaN(p_params.period) ? d*.3 : p_params.period;\r
//var s:Number;\r
//var a:Number = !Boolean(p_params) || isNaN(p_params.amplitude) ? 0 : p_params.amplitude;\r
- double p = d*0.3;\r
+ double p = params.size() > 0 ? params[0] : d*0.3;\r
double s;\r
- double a = 0.0;\r
+ double a = params.size() > 1 ? params[1] : 0.0;\r
if (a == 0.0 || a < std::abs(c))\r
{\r
a = c;\r
return (a*std::pow(2,-10*t) * std::sin( (t*d-s)*(2*PI)/p ) + c + b);\r
} \r
\r
-inline double ease_in_out_elastic (double t, double b, double c, double d) \r
+inline double ease_in_out_elastic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if (t==0)\r
return b;\r
//var p:Number = !Boolean(p_params) || isNaN(p_params.period) ? d*(.3*1.5) : p_params.period;\r
//var s:Number;\r
//var a:Number = !Boolean(p_params) || isNaN(p_params.amplitude) ? 0 : p_params.amplitude;\r
- double p = d*0.3*1.5;\r
+ double p = params.size() > 0 ? params[0] : d*0.3*1.5;\r
double s;\r
- double a = 0.0;\r
+ double a = params.size() > 1 ? params[1] : 0.0;\r
if (a == 0.0 || a < std::abs(c)) \r
{\r
a = c;\r
return a*std::pow(2,-10*(t-=1)) * std::sin( (t*d-s)*(2*PI)/p )*.5 + c + b;\r
}\r
\r
-inline double ease_out_in_elastic (double t, double b, double c, double d) \r
+inline double ease_out_in_elastic (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
- if (t < d/2) return ease_out_elastic (t*2, b, c/2, d);\r
- return ease_in_elastic((t*2)-d, b+c/2, c/2, d);\r
+ if (t < d/2) return ease_out_elastic (t*2, b, c/2, d, params);\r
+ return ease_in_elastic((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-inline double ease_in_back (double t, double b, double c, double d) \r
+inline double ease_in_back (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
//var s:Number = !Boolean(p_params) || isNaN(p_params.overshoot) ? 1.70158 : p_params.overshoot;\r
- double s = 1.70158;\r
+ double s = params.size() > 0 ? params[0] : 1.70158;\r
return c*(t/=d)*t*((s+1)*t - s) + b;\r
}\r
\r
-inline double ease_out_back (double t, double b, double c, double d)\r
+inline double ease_out_back (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
//var s:Number = !Boolean(p_params) || isNaN(p_params.overshoot) ? 1.70158 : p_params.overshoot;\r
- double s = 1.70158;\r
+ double s = params.size() > 0 ? params[0] : 1.70158;\r
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;\r
}\r
\r
-inline double ease_in_out_back (double t, double b, double c, double d)\r
+inline double ease_in_out_back (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
//var s:Number = !Boolean(p_params) || isNaN(p_params.overshoot) ? 1.70158 : p_params.overshoot;\r
- double s = 1.70158;\r
+ double s = params.size() > 0 ? params[0] : 1.70158;\r
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;\r
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;\r
}\r
\r
-\r
-inline double ease_out_int_back (double t, double b, double c, double d)\r
+inline double ease_out_int_back (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
- if (t < d/2) return ease_out_back (t*2, b, c/2, d);\r
- return ease_in_back((t*2)-d, b+c/2, c/2, d);\r
+ if (t < d/2) return ease_out_back (t*2, b, c/2, d, params);\r
+ return ease_in_back((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-\r
-inline double ease_out_bounce (double t, double b, double c, double d) \r
+inline double ease_out_bounce (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
if ((t/=d) < (1/2.75))\r
return c*(7.5625*t*t) + b;\r
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; \r
}\r
\r
-inline double ease_in_bounce (double t, double b, double c, double d)\r
+inline double ease_in_bounce (double t, double b, double c, double d, const std::vector<double>& params)\r
{\r
- return c - ease_out_bounce (d-t, 0, c, d) + b;\r
+ return c - ease_out_bounce (d-t, 0, c, d, params) + b;\r
}\r
\r
-inline double ease_in_out_bounce (double t, double b, double c, double d) \r
+inline double ease_in_out_bounce (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
- if (t < d/2) return ease_in_bounce (t*2, 0, c, d) * .5 + b;\r
- else return ease_out_bounce (t*2-d, 0, c, d) * .5 + c*.5 + b;\r
+ if (t < d/2) return ease_in_bounce (t*2, 0, c, d, params) * .5 + b;\r
+ else return ease_out_bounce (t*2-d, 0, c, d, params) * .5 + c*.5 + b;\r
}\r
\r
\r
-inline double ease_out_in_bounce (double t, double b, double c, double d) \r
+inline double ease_out_in_bounce (double t, double b, double c, double d, const std::vector<double>& params) \r
{\r
- if (t < d/2) return ease_out_bounce (t*2, b, c/2, d);\r
- return ease_in_bounce((t*2)-d, b+c/2, c/2, d);\r
+ if (t < d/2) return ease_out_bounce (t*2, b, c/2, d, params);\r
+ return ease_in_bounce((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
inline tweener_t get_tweener(std::wstring name = L"linear")\r
{\r
std::transform(name.begin(), name.end(), name.begin(), std::tolower);\r
\r
- static const std::unordered_map<std::wstring, tweener_t> tweens = boost::assign::map_list_of \r
+ if(name == L"linear")\r
+ return [](double t, double b, double c, double d){return ease_none(t, b, c, d, std::vector<double>());};\r
+ \r
+ std::vector<double> params;\r
+ \r
+ static const boost::wregex expr(L"(?<NAME>\\w*)(:(?<V0>\\d+\\.?\\d?))?(:(?<V1>\\d+\\.?\\d?))?"); // boost::regex has no repeated captures?\r
+ boost::wsmatch what;\r
+ if(boost::regex_match(name, what, expr))\r
+ {\r
+ name = what["NAME"].str();\r
+ if(what["V0"].matched)\r
+ params.push_back(boost::lexical_cast<double>(what["V0"].str()));\r
+ if(what["V1"].matched)\r
+ params.push_back(boost::lexical_cast<double>(what["V1"].str()));\r
+ }\r
+ \r
+ typedef std::function<double(double, double, double, double, const std::vector<double>&)> tween_t; \r
+ static const std::unordered_map<std::wstring, tween_t> tweens = boost::assign::map_list_of \r
(L"", ease_none ) \r
(L"linear", ease_none ) \r
(L"easenone", ease_none )\r
it = tweens.find(L"linear");\r
}\r
\r
- return it->second;\r
+ return [=](double t, double b, double c, double d)\r
+ {\r
+ return it->second(t, b, c, d, params);\r
+ };\r
};\r
\r
}
\ No newline at end of file