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_COL 10
#define NUM_PER_COL 9
#define SIZE (WIDTH/NUM_PER_ROW)
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 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)
{
mathIdentity(&matrix);
@ -84,6 +110,11 @@ static bool _updateTransform(LottieTransform* transform, int32_t frameNo, bool a
if (autoOrient) angle = transform->position.angle(frameNo);
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);
mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f);

View file

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

View file

@ -502,7 +502,10 @@ LottieTransform* LottieParser::parseTransform(bool ddd)
auto transform = new LottieTransform;
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()) {
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, "r")) parseProperty(transform->rotation);
else if (!strcmp(key, "o")) parseProperty(transform->opacity);
//else if (!strcmp(key, "sk")) //skew
//else if (!strcmp(key, "sa")) //skew axis
//else if (!strcmp(key, "rx") //3d rotation
//else if (!strcmp(key, "ry") //3d rotation
else if (!strcmp(key, "rz")) parseProperty(transform->rotation);
else if (transform->rotationEx && !strcmp(key, "rx")) parseProperty(transform->rotationEx->x);
else if (transform->rotationEx && !strcmp(key, "ry")) parseProperty(transform->rotationEx->y);
else if (transform->rotationEx && !strcmp(key, "rz")) parseProperty(transform->rotation);
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);
}
transform->prepare();