+ float result = progress;
+
+ AlphaFunction::Mode alphaFunctionMode(mAlphaFunction.GetMode());
+ if(alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION)
+ {
+ switch(mAlphaFunction.GetBuiltinFunction())
+ {
+ case AlphaFunction::DEFAULT:
+ case AlphaFunction::LINEAR:
+ {
+ break;
+ }
+ case AlphaFunction::REVERSE:
+ {
+ result = 1.0f - progress;
+ break;
+ }
+ case AlphaFunction::EASE_IN_SQUARE:
+ {
+ result = progress * progress;
+ break;
+ }
+ case AlphaFunction::EASE_OUT_SQUARE:
+ {
+ result = 1.0f - (1.0f - progress) * (1.0f - progress);
+ break;
+ }
+ case AlphaFunction::EASE_IN:
+ {
+ result = progress * progress * progress;
+ break;
+ }
+ case AlphaFunction::EASE_OUT:
+ {
+ result = (progress - 1.0f) * (progress - 1.0f) * (progress - 1.0f) + 1.0f;
+ break;
+ }
+ case AlphaFunction::EASE_IN_OUT:
+ {
+ result = progress * progress * (3.0f - 2.0f * progress);
+ break;
+ }
+ case AlphaFunction::EASE_IN_SINE:
+ {
+ result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
+ break;
+ }
+ case AlphaFunction::EASE_OUT_SINE:
+ {
+ result = sinf(progress * Math::PI_2);
+ break;
+ }
+ case AlphaFunction::EASE_IN_OUT_SINE:
+ {
+ result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
+ break;
+ }
+ case AlphaFunction::BOUNCE:
+ {
+ result = sinf(progress * Math::PI);
+ break;
+ }
+ case AlphaFunction::SIN:
+ {
+ result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
+ break;
+ }
+ case AlphaFunction::EASE_OUT_BACK:
+ {
+ const float sqrt2 = 1.70158f;
+ progress -= 1.0f;
+ result = 1.0f + progress * progress * ((sqrt2 + 1.0f) * progress + sqrt2);
+ break;
+ }
+ case AlphaFunction::COUNT:
+ {
+ break;
+ }
+ }
+ }
+ else if(alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION)
+ {
+ AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
+ if(customFunction)
+ {
+ result = customFunction(progress);
+ }
+ }
+ else
+ {
+ //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
+ //be almost 0 or almost 1 respectively
+ if((progress > Math::MACHINE_EPSILON_1) && ((1.0f - progress) > Math::MACHINE_EPSILON_1))
+ {
+ Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
+
+ static const float tolerance = 0.001f; //10 iteration max
+
+ //Perform a binary search on the curve
+ float lowerBound(0.0f);
+ float upperBound(1.0f);
+ float currentT(0.5f);
+ float currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
+ while(fabsf(progress - currentX) > tolerance)
+ {
+ if(progress > currentX)
+ {
+ lowerBound = currentT;
+ }
+ else
+ {
+ upperBound = currentT;
+ }
+ currentT = (upperBound + lowerBound) * 0.5f;
+ currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
+ }
+ result = EvaluateCubicBezier(controlPoints.y, controlPoints.w, currentT);
+ }
+ }
+
+ return result;