diff --git a/src/common/tvgMath.h b/src/common/tvgMath.h index e09fc1a3..5f2fe9ef 100644 --- a/src/common/tvgMath.h +++ b/src/common/tvgMath.h @@ -29,6 +29,8 @@ #include #include "tvgCommon.h" +#define MATH_PI 3.14159265358979323846f +#define MATH_PI2 1.57079632679489661923f #define mathMin(x, y) (((x) < (y)) ? (x) : (y)) #define mathMax(x, y) (((x) > (y)) ? (x) : (y)) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index bb578a7c..f137394a 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -242,7 +242,6 @@ static Shape* _updatePath(LottieGroup* parent, LottiePath* path, int32_t frameNo static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, int32_t frameNo, Shape* mergingShape) { - static constexpr auto K_PI = 3.141592f; static constexpr auto POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f; auto ptsCnt = star->ptsCnt(frameNo); @@ -251,9 +250,9 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans auto innerRoundness = star->innerRoundness(frameNo) * 0.01f; auto outerRoundness = star->outerRoundness(frameNo) * 0.01f; - auto angle = -90.0f * K_PI / 180.0f; + auto angle = -90.0f * MATH_PI / 180.0f; auto partialPointRadius = 0.0f; - auto anglePerPoint = (2.0f * K_PI / ptsCnt); + auto anglePerPoint = (2.0f * MATH_PI / ptsCnt); auto halfAnglePerPoint = anglePerPoint * 0.5f; auto partialPointAmount = ptsCnt - floorf(ptsCnt); auto longSegment = false; @@ -306,10 +305,10 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans y = radius * sinf(angle); if (hasRoundness) { - auto cp1Theta = (atan2f(previousY, previousX) - K_PI / 2.0f * direction); + auto cp1Theta = (atan2f(previousY, previousX) - MATH_PI2 * direction); auto cp1Dx = cosf(cp1Theta); auto cp1Dy = sinf(cp1Theta); - auto cp2Theta = (atan2f(y, x) - K_PI / 2.0f * direction); + auto cp2Theta = (atan2f(y, x) - MATH_PI2 * direction); auto cp2Dx = cosf(cp2Theta); auto cp2Dy = sinf(cp2Theta); @@ -353,14 +352,13 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, int32_t frameNo, Shape* mergingShape) { static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f; - static constexpr auto K_PI = 3.141592f; auto ptsCnt = size_t(floor(star->ptsCnt(frameNo))); auto radius = star->outerRadius(frameNo); auto roundness = star->outerRoundness(frameNo) * 0.01f; - auto angle = -90.0f * K_PI / 180.0f; - auto anglePerPoint = 2.0f * K_PI / float(ptsCnt); + auto angle = -90.0f * MATH_PI / 180.0f; + auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt); auto direction = star->cw ? 1.0f : -1.0f; auto hasRoundness = false; auto x = radius * cosf(angle); @@ -388,10 +386,10 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr y = (radius * sinf(angle)); if (hasRoundness) { - auto cp1Theta = atan2f(previousY, previousX) - K_PI * 0.5f * direction; + auto cp1Theta = atan2f(previousY, previousX) - MATH_PI2 * direction; auto cp1Dx = cosf(cp1Theta); auto cp1Dy = sinf(cp1Theta); - auto cp2Theta = atan2f(y, x) - K_PI * 0.5f * direction; + auto cp2Theta = atan2f(y, x) - MATH_PI2 * direction; auto cp2Dx = cosf(cp2Theta); auto cp2Dy = sinf(cp2Theta); @@ -735,7 +733,10 @@ static void _bulidHierarchy(LottieGroup* parent, LottieLayer* child) static void _buildSize(LottieComposition* comp, LottieLayer* layer) { - // default size is 0x0 + //should not clip? + if (layer->refId) return; + + //default size is 0x0 if (layer->w == 0 || layer->h == 0) return; //compact layer size diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 55439026..63951d2f 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -20,6 +20,7 @@ * SOFTWARE. */ +#include "tvgFill.h" #include "tvgLottieModel.h" @@ -88,14 +89,27 @@ Fill* LottieGradient::fill(int32_t frameNo) //Radial Gradient if (id == 2) { fill = RadialGradient::gen().release(); + auto sx = start(frameNo).x; auto sy = start(frameNo).y; - auto w = fabsf(end(frameNo).x - sx); - auto h = fabsf(end(frameNo).y - sy); - auto radius = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w); - static_cast(fill)->radial(sx, sy, radius); + auto ex = end(frameNo).x; + auto ey = end(frameNo).y; + auto w = fabsf(ex - sx); + auto h = fabsf(ey - sy); + auto r = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w); + auto progress = this->height(frameNo) * 0.01f; - //TODO: focal support? + if (mathZero(progress)) { + P(static_cast(fill))->radial(sx, sy, r, sx, sy, 0.0f); + } else { + if (mathEqual(progress, 1.0f)) progress = 0.99f; + auto startAngle = atan2(ey - sy, ex - sx) * 180.0f / MATH_PI; + auto angle = (startAngle + this->angle(frameNo)) * (MATH_PI / 180.0f); + auto fx = sx + cos(angle) * progress * r; + auto fy = sy + sin(angle) * progress * r; + // Lottie dosen't have any focal radius concept + P(static_cast(fill))->radial(sx, sy, r, fx, fy, 0.0f); + } } if (!fill) return nullptr; diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index cb68da50..9ea21fd6 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -91,7 +91,7 @@ struct LottieGradient LottiePoint start = Point{0.0f, 0.0f}; LottiePoint end = Point{0.0f, 0.0f}; LottieOpacity opacity = 255; - LottieFloat height = 0.0f; //TODO: + LottieFloat height = 0.0f; LottieFloat angle = 0.0f; LottieColorStop colorStops; uint8_t id = 0; //1: linear, 2: radial diff --git a/src/renderer/gl_engine/tvgGlGeometry.h b/src/renderer/gl_engine/tvgGlGeometry.h index 3dcf0ddb..369cd949 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.h +++ b/src/renderer/gl_engine/tvgGlGeometry.h @@ -23,12 +23,11 @@ #ifndef _TVG_GL_GEOMETRY_H_ #define _TVG_GL_GEOMETRY_H_ -#include #include +#include "tvgMath.h" #include "tvgArray.h" #include "tvgGlCommon.h" -#define PI 3.1415926535897932384626433832795f #define MVP_MATRIX() \ float mvp[4*4] = { \ diff --git a/src/renderer/tvgShape.cpp b/src/renderer/tvgShape.cpp index f07e8803..3e422aae 100644 --- a/src/renderer/tvgShape.cpp +++ b/src/renderer/tvgShape.cpp @@ -150,13 +150,13 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa //just circle if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); - startAngle = (startAngle * M_PI) / 180.0f; - sweep = sweep * M_PI / 180.0f; + startAngle = (startAngle * MATH_PI) / 180.0f; + sweep = sweep * MATH_PI / 180.0f; - auto nCurves = ceil(fabsf(sweep / float(M_PI_2))); + auto nCurves = ceil(fabsf(sweep / MATH_PI2)); auto sweepSign = (sweep < 0 ? -1 : 1); - auto fract = fmodf(sweep, float(M_PI_2)); - fract = (mathZero(fract)) ? float(M_PI_2) * sweepSign : fract; + auto fract = fmodf(sweep, MATH_PI2); + fract = (mathZero(fract)) ? MATH_PI2 * sweepSign : fract; //Start from here Point start = {radius * cosf(startAngle), radius * sinf(startAngle)};