mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
lottie: 3d transformations enhancement
This commit is contained in:
parent
bb5ba81149
commit
bdbc0a2595
2 changed files with 42 additions and 16 deletions
|
@ -38,19 +38,32 @@ static bool _buildComposition(LottieComposition* comp, LottieLayer* parent);
|
||||||
static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx);
|
static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx);
|
||||||
|
|
||||||
|
|
||||||
static void _rotationXYZ(Matrix* m, float degreeX, float degreeY, float degreeZ)
|
static void _rotationXYZ(Matrix* m, float degreeX, float degreeY, float degreeZ, Matrix* rotation3d)
|
||||||
{
|
{
|
||||||
auto radianX = deg2rad(degreeX);
|
auto radianX = deg2rad(degreeX);
|
||||||
auto radianY = deg2rad(degreeY);
|
auto radianY = deg2rad(degreeY);
|
||||||
auto radianZ = deg2rad(degreeZ);
|
auto radianZ = deg2rad(degreeZ);
|
||||||
|
|
||||||
auto cx = cosf(radianX), sx = sinf(radianX);
|
auto cx = cosf(radianX), sx = sinf(radianX);
|
||||||
auto cy = cosf(radianY), sy = sinf(radianY);;
|
auto cy = cosf(radianY), sy = sinf(radianY);
|
||||||
auto cz = cosf(radianZ), sz = sinf(radianZ);;
|
auto cz = cosf(radianZ), sz = sinf(radianZ);
|
||||||
m->e11 = cy * cz;
|
|
||||||
m->e12 = -cy * sz;
|
rotation3d->e11 = cy * cz;
|
||||||
m->e21 = sx * sy * cz + cx * sz;
|
rotation3d->e12 = -cy * sz;
|
||||||
m->e22 = -sx * sy * sz + cx * cz;
|
rotation3d->e13 = -sy;
|
||||||
|
|
||||||
|
rotation3d->e21 = cz * sy * sx + sz * cx;
|
||||||
|
rotation3d->e22 = -sz * sy * sx + cz * cx;
|
||||||
|
rotation3d->e23 = cy * sx;
|
||||||
|
|
||||||
|
rotation3d->e31 = cz * sy * cx - sz * sx;
|
||||||
|
rotation3d->e32 = -sz * sy * cx - cz * sx;
|
||||||
|
rotation3d->e33 = cy * cx;
|
||||||
|
|
||||||
|
m->e11 = rotation3d->e11;
|
||||||
|
m->e12 = rotation3d->e12;
|
||||||
|
m->e21 = rotation3d->e21;
|
||||||
|
m->e22 = rotation3d->e22;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +114,7 @@ static void _skew(Matrix* m, float angleDeg, float axisDeg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _updateTransform(LottieTransform* transform, float frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity, LottieExpressions* exps)
|
static bool _updateTransform(LottieTransform* transform, float frameNo, bool autoOrient, Matrix& matrix, Matrix* rotation3d, uint8_t& opacity, LottieExpressions* exps)
|
||||||
{
|
{
|
||||||
identity(&matrix);
|
identity(&matrix);
|
||||||
|
|
||||||
|
@ -119,7 +132,7 @@ static bool _updateTransform(LottieTransform* transform, float frameNo, bool aut
|
||||||
|
|
||||||
auto angle = 0.0f;
|
auto angle = 0.0f;
|
||||||
if (autoOrient) angle = transform->position.angle(frameNo);
|
if (autoOrient) angle = transform->position.angle(frameNo);
|
||||||
if (transform->rotationEx) _rotationXYZ(&matrix, transform->rotationEx->x(frameNo, exps), transform->rotationEx->y(frameNo, exps), transform->rotation(frameNo, exps) + angle);
|
if (transform->rotationEx) _rotationXYZ(&matrix, transform->rotationEx->x(frameNo, exps), transform->rotationEx->y(frameNo, exps), transform->rotation(frameNo, exps) + angle, rotation3d);
|
||||||
else _rotationZ(&matrix, transform->rotation(frameNo, exps) + angle);
|
else _rotationZ(&matrix, transform->rotation(frameNo, exps) + angle);
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,13 +170,25 @@ void LottieBuilder::updateTransform(LottieLayer* layer, float frameNo)
|
||||||
if (parent) updateTransform(parent, frameNo);
|
if (parent) updateTransform(parent, frameNo);
|
||||||
|
|
||||||
auto& matrix = layer->cache.matrix;
|
auto& matrix = layer->cache.matrix;
|
||||||
|
auto& rotation3d = layer->cache.rotation3d;
|
||||||
|
_updateTransform(transform, frameNo, layer->autoOrient, matrix, &rotation3d, layer->cache.opacity, exps);
|
||||||
|
|
||||||
_updateTransform(transform, frameNo, layer->autoOrient, matrix, layer->cache.opacity, exps);
|
if (parent && !identity((const Matrix*)&parent->cache.matrix)) {
|
||||||
|
if (identity((const Matrix*)&matrix)) { //TODO: test
|
||||||
|
layer->cache.matrix = parent->cache.matrix;
|
||||||
|
layer->cache.rotation3d = parent->cache.rotation3d;
|
||||||
|
} else {
|
||||||
|
layer->cache.matrix = parent->cache.matrix * matrix;
|
||||||
|
|
||||||
if (parent) {
|
if (transform->rotationEx) {
|
||||||
if (!identity((const Matrix*) &parent->cache.matrix)) {
|
//include remaining terms from the 3d rotation matrix:
|
||||||
if (identity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix;
|
layer->cache.matrix.e11 += parent->cache.rotation3d.e13 * rotation3d.e31;
|
||||||
else layer->cache.matrix = parent->cache.matrix * matrix;
|
layer->cache.matrix.e21 += parent->cache.rotation3d.e23 * rotation3d.e31;
|
||||||
|
layer->cache.matrix.e12 += parent->cache.rotation3d.e13 * rotation3d.e32;
|
||||||
|
layer->cache.matrix.e22 += parent->cache.rotation3d.e23 * rotation3d.e32;
|
||||||
|
|
||||||
|
layer->cache.rotation3d = parent->cache.rotation3d * rotation3d; //TODO: test
|
||||||
|
} else layer->cache.rotation3d = parent->cache.rotation3d; //TODO: test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layer->cache.frameNo = frameNo;
|
layer->cache.frameNo = frameNo;
|
||||||
|
@ -179,14 +204,14 @@ void LottieBuilder::updateTransform(LottieGroup* parent, LottieObject** child, f
|
||||||
|
|
||||||
if (parent->mergeable()) {
|
if (parent->mergeable()) {
|
||||||
if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix));
|
if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix));
|
||||||
_updateTransform(transform, frameNo, false, *ctx->transform, opacity, exps);
|
_updateTransform(transform, frameNo, false, *ctx->transform, nullptr, opacity, exps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->merging = nullptr;
|
ctx->merging = nullptr;
|
||||||
|
|
||||||
Matrix matrix;
|
Matrix matrix;
|
||||||
if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return;
|
if (!_updateTransform(transform, frameNo, false, matrix, nullptr, opacity, exps)) return;
|
||||||
|
|
||||||
ctx->propagator->transform(ctx->propagator->transform() * matrix);
|
ctx->propagator->transform(ctx->propagator->transform() * matrix);
|
||||||
ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity));
|
ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity));
|
||||||
|
|
|
@ -796,6 +796,7 @@ struct LottieLayer : LottieGroup
|
||||||
struct {
|
struct {
|
||||||
float frameNo = -1.0f;
|
float frameNo = -1.0f;
|
||||||
Matrix matrix;
|
Matrix matrix;
|
||||||
|
Matrix rotation3d;
|
||||||
uint8_t opacity;
|
uint8_t opacity;
|
||||||
} cache;
|
} cache;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue