loader/lottie: support focal property in the radial gradient

This commit is contained in:
Hermet Park 2023-09-04 18:26:14 +09:00 committed by Hermet Park
parent fa134692b0
commit 64a444aeb6
6 changed files with 40 additions and 24 deletions

View file

@ -29,6 +29,8 @@
#include <math.h>
#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))

View file

@ -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

View file

@ -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<RadialGradient*>(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<RadialGradient*>(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<RadialGradient*>(fill))->radial(sx, sy, r, fx, fy, 0.0f);
}
}
if (!fill) return nullptr;

View file

@ -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

View file

@ -23,12 +23,11 @@
#ifndef _TVG_GL_GEOMETRY_H_
#define _TVG_GL_GEOMETRY_H_
#include <math.h>
#include <vector>
#include "tvgMath.h"
#include "tvgArray.h"
#include "tvgGlCommon.h"
#define PI 3.1415926535897932384626433832795f
#define MVP_MATRIX() \
float mvp[4*4] = { \

View file

@ -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)};