loader/lottie: minimum support for 3D transform

It lacks perspective projection information,
so it transforms 3D axes with orthogonal projection.
This commit is contained in:
Hermet Park 2023-09-07 16:29:50 +09:00 committed by Hermet Park
parent b5fcc90e5d
commit 516e8bf042
11 changed files with 56 additions and 13 deletions

View file

@ -30,7 +30,7 @@
/************************************************************************/ /************************************************************************/
#define NUM_PER_ROW 10 #define NUM_PER_ROW 10
#define NUM_PER_COL 10 #define NUM_PER_COL 9
#define SIZE (WIDTH/NUM_PER_ROW) #define SIZE (WIDTH/NUM_PER_ROW)
static int counter = 0; static int counter = 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -64,6 +64,32 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, int32_t frameNo)
static bool _buildPrecomp(LottieComposition* comp, LottieGroup* parent); static bool _buildPrecomp(LottieComposition* comp, LottieGroup* parent);
static void _rotateY(Matrix* m, float degree)
{
if (degree == 0.0f) return;
auto radian = degree / 180.0f * M_PI;
auto cosVal = cosf(radian);
auto sinVal = sinf(radian);
m->e11 = cosVal;
m->e31 = -sinVal;
}
static void _rotateX(Matrix* m, float degree)
{
if (degree == 0.0f) return;
auto radian = degree / 180.0f * M_PI;
auto cosVal = cosf(radian);
auto sinVal = sinf(radian);
m->e22 = cosVal;
m->e32 = -sinVal;
}
static bool _updateTransform(LottieTransform* transform, int32_t frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity) static bool _updateTransform(LottieTransform* transform, int32_t frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity)
{ {
mathIdentity(&matrix); mathIdentity(&matrix);
@ -84,6 +110,11 @@ static bool _updateTransform(LottieTransform* transform, int32_t frameNo, bool a
if (autoOrient) angle = transform->position.angle(frameNo); if (autoOrient) angle = transform->position.angle(frameNo);
mathRotate(&matrix, transform->rotation(frameNo) + angle); mathRotate(&matrix, transform->rotation(frameNo) + angle);
if (transform->rotationEx) {
_rotateY(&matrix, transform->rotationEx->y(frameNo));
_rotateX(&matrix, transform->rotationEx->x(frameNo));
}
auto scale = transform->scale(frameNo); auto scale = transform->scale(frameNo);
mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f); mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f);

View file

@ -253,9 +253,16 @@ struct LottieTransform : LottieObject
LottieFloat y = 0.0f; LottieFloat y = 0.0f;
}; };
struct RotationEx
{
LottieFloat x = 0.0f;
LottieFloat y = 0.0f;
};
~LottieTransform() ~LottieTransform()
{ {
delete(coords); delete(coords);
delete(rotationEx);
} }
void prepare() void prepare()
@ -263,16 +270,17 @@ struct LottieTransform : LottieObject
LottieObject::type = LottieObject::Transform; LottieObject::type = LottieObject::Transform;
if (position.frames || rotation.frames || scale.frames || anchor.frames || opacity.frames) statical = false; if (position.frames || rotation.frames || scale.frames || anchor.frames || opacity.frames) statical = false;
else if (coords && (coords->x.frames || coords->y.frames)) statical = false; else if (coords && (coords->x.frames || coords->y.frames)) statical = false;
else if (rotationEx && (rotationEx->x.frames || rotationEx->y.frames)) statical = false;
} }
LottiePosition position = Point{0.0f, 0.0f}; LottiePosition position = Point{0.0f, 0.0f};
LottieFloat rotation = 0.0f; LottieFloat rotation = 0.0f; //z rotation
LottiePoint scale = Point{100.0f, 100.0f}; LottiePoint scale = Point{100.0f, 100.0f};
LottiePoint anchor = Point{0.0f, 0.0f}; LottiePoint anchor = Point{0.0f, 0.0f};
LottieOpacity opacity = 255; LottieOpacity opacity = 255;
//either a position or separate coordinates SeparateCoord* coords = nullptr; //either a position or separate coordinates
SeparateCoord* coords = nullptr; RotationEx* rotationEx = nullptr; //extension for 3d rotation
}; };

View file

@ -502,7 +502,10 @@ LottieTransform* LottieParser::parseTransform(bool ddd)
auto transform = new LottieTransform; auto transform = new LottieTransform;
if (!transform) return nullptr; if (!transform) return nullptr;
if (ddd) TVGERR("LOTTIE", "3d transform(ddd) is not supported"); if (ddd) {
transform->rotationEx = new LottieTransform::RotationEx;
TVGLOG("LOTTIE", "3D transform(ddd) is not 100% compatible.");
}
while (auto key = nextObjectKey()) { while (auto key = nextObjectKey()) {
if (!strcmp(key, "p")) if (!strcmp(key, "p"))
@ -524,12 +527,12 @@ LottieTransform* LottieParser::parseTransform(bool ddd)
else if (!strcmp(key, "s")) parseProperty(transform->scale); else if (!strcmp(key, "s")) parseProperty(transform->scale);
else if (!strcmp(key, "r")) parseProperty(transform->rotation); else if (!strcmp(key, "r")) parseProperty(transform->rotation);
else if (!strcmp(key, "o")) parseProperty(transform->opacity); else if (!strcmp(key, "o")) parseProperty(transform->opacity);
//else if (!strcmp(key, "sk")) //skew else if (transform->rotationEx && !strcmp(key, "rx")) parseProperty(transform->rotationEx->x);
//else if (!strcmp(key, "sa")) //skew axis else if (transform->rotationEx && !strcmp(key, "ry")) parseProperty(transform->rotationEx->y);
//else if (!strcmp(key, "rx") //3d rotation else if (transform->rotationEx && !strcmp(key, "rz")) parseProperty(transform->rotation);
//else if (!strcmp(key, "ry") //3d rotation
else if (!strcmp(key, "rz")) parseProperty(transform->rotation);
else if (!strcmp(key, "nm")) transform->name = getStringCopy(); else if (!strcmp(key, "nm")) transform->name = getStringCopy();
//else if (!strcmp(key, "sk")) //TODO: skew
//else if (!strcmp(key, "sa")) //TODO: skew axis
else skip(key); else skip(key);
} }
transform->prepare(); transform->prepare();