mirror of https://github.com/procxx/kepka.git
QtLottie: Make property parsing non-virtual.
This commit is contained in:
parent
38e2837cb6
commit
12a4a849ca
|
@ -1 +1 @@
|
||||||
Subproject commit 2fa825bfd9384b864e79861e8fa41273da8ab973
|
Subproject commit f95d9f5260af2dcf1e724d1d0814bd9176149b76
|
|
@ -69,7 +69,6 @@ struct EasingSegment {
|
||||||
T startValue;
|
T startValue;
|
||||||
T endValue;
|
T endValue;
|
||||||
BezierEasing easing;
|
BezierEasing easing;
|
||||||
QPainterPath bezier;
|
|
||||||
|
|
||||||
double bezierLength = 0.;
|
double bezierLength = 0.;
|
||||||
struct BezierPoint {
|
struct BezierPoint {
|
||||||
|
@ -85,7 +84,7 @@ class BODYMOVIN_EXPORT BMProperty
|
||||||
public:
|
public:
|
||||||
virtual ~BMProperty() = default;
|
virtual ~BMProperty() = default;
|
||||||
|
|
||||||
virtual void construct(const QJsonObject &definition)
|
void construct(const QJsonObject &definition)
|
||||||
{
|
{
|
||||||
if (definition.value(QStringLiteral("s")).toVariant().toInt())
|
if (definition.value(QStringLiteral("s")).toVariant().toInt())
|
||||||
qCWarning(lcLottieQtBodymovinParser)
|
qCWarning(lcLottieQtBodymovinParser)
|
||||||
|
@ -210,7 +209,7 @@ protected:
|
||||||
return m_currentEasing;
|
return m_currentEasing;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual EasingSegment<T> parseKeyframe(const QJsonObject keyframe)
|
EasingSegment<T> parseKeyframe(const QJsonObject keyframe)
|
||||||
{
|
{
|
||||||
EasingSegment<T> easing;
|
EasingSegment<T> easing;
|
||||||
|
|
||||||
|
@ -251,6 +250,7 @@ protected:
|
||||||
QJsonObject easingIn = keyframe.value(QStringLiteral("i")).toObject();
|
QJsonObject easingIn = keyframe.value(QStringLiteral("i")).toObject();
|
||||||
QJsonObject easingOut = keyframe.value(QStringLiteral("o")).toObject();
|
QJsonObject easingOut = keyframe.value(QStringLiteral("o")).toObject();
|
||||||
|
|
||||||
|
if (easingIn.value(QStringLiteral("x")).isArray()) {
|
||||||
qreal eix = easingIn.value(QStringLiteral("x")).toArray().at(0).toDouble();
|
qreal eix = easingIn.value(QStringLiteral("x")).toArray().at(0).toDouble();
|
||||||
qreal eiy = easingIn.value(QStringLiteral("y")).toArray().at(0).toDouble();
|
qreal eiy = easingIn.value(QStringLiteral("y")).toArray().at(0).toDouble();
|
||||||
|
|
||||||
|
@ -261,13 +261,25 @@ protected:
|
||||||
QPointF c2 = QPointF(eix, eiy);
|
QPointF c2 = QPointF(eix, eiy);
|
||||||
|
|
||||||
easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0));
|
easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0));
|
||||||
|
} else {
|
||||||
|
qreal eix = easingIn.value(QStringLiteral("x")).toDouble();
|
||||||
|
qreal eiy = easingIn.value(QStringLiteral("y")).toDouble();
|
||||||
|
|
||||||
|
qreal eox = easingOut.value(QStringLiteral("x")).toDouble();
|
||||||
|
qreal eoy = easingOut.value(QStringLiteral("y")).toDouble();
|
||||||
|
|
||||||
|
QPointF c1 = QPointF(eox, eoy);
|
||||||
|
QPointF c2 = QPointF(eix, eiy);
|
||||||
|
|
||||||
|
easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
return easing;
|
return easing;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void postprocessEasingCurve(
|
virtual void postprocessEasingCurve(
|
||||||
EasingSegment<T> &easing,
|
EasingSegment<T> &easing,
|
||||||
const QJsonObject keyframe) {
|
const QJsonObject &keyframe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual T getValue(const QJsonValue &value)
|
virtual T getValue(const QJsonValue &value)
|
||||||
|
@ -302,10 +314,9 @@ protected:
|
||||||
const EasingSegment<T> *m_currentEasing = nullptr;
|
const EasingSegment<T> *m_currentEasing = nullptr;
|
||||||
int m_startFrame = INT_MAX;
|
int m_startFrame = INT_MAX;
|
||||||
int m_endFrame = 0;
|
int m_endFrame = 0;
|
||||||
T m_value;
|
T m_value = T();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class BODYMOVIN_EXPORT BMProperty2D : public BMProperty<T>
|
class BODYMOVIN_EXPORT BMProperty2D : public BMProperty<T>
|
||||||
{
|
{
|
||||||
|
@ -318,95 +329,6 @@ protected:
|
||||||
else
|
else
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
EasingSegment<T> parseKeyframe(const QJsonObject keyframe) override
|
|
||||||
{
|
|
||||||
QJsonArray startValues = keyframe.value(QStringLiteral("s")).toArray();
|
|
||||||
QJsonArray endValues = keyframe.value(QStringLiteral("e")).toArray();
|
|
||||||
int startTime = keyframe.value(QStringLiteral("t")).toVariant().toInt();
|
|
||||||
|
|
||||||
EasingSegment<T> easingCurve;
|
|
||||||
easingCurve.startFrame = startTime;
|
|
||||||
|
|
||||||
// AE exported Bodymovin file includes the last
|
|
||||||
// key frame but no other properties.
|
|
||||||
// No need to process in that case
|
|
||||||
if (startValues.isEmpty() && endValues.isEmpty()) {
|
|
||||||
// In this case start time is the last frame for the property
|
|
||||||
this->m_endFrame = startTime;
|
|
||||||
easingCurve.startFrame = startTime;
|
|
||||||
easingCurve.endFrame = startTime;
|
|
||||||
easingCurve.state = EasingSegmentState::Final;
|
|
||||||
if (this->m_easingCurves.length()) {
|
|
||||||
const EasingSegment<T> &last = this->m_easingCurves.last();
|
|
||||||
if (last.state == EasingSegmentState::Complete) {
|
|
||||||
easingCurve.startValue = last.endValue;
|
|
||||||
easingCurve.endValue = last.endValue;
|
|
||||||
} else {
|
|
||||||
qCWarning(lcLottieQtBodymovinParser())
|
|
||||||
<< "Last keyframe found after an incomplete one";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return easingCurve;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->m_startFrame > startTime)
|
|
||||||
this->m_startFrame = startTime;
|
|
||||||
|
|
||||||
qreal xs, ys;
|
|
||||||
xs = startValues.at(0).toDouble();
|
|
||||||
ys = startValues.at(1).toDouble();
|
|
||||||
T s(xs, ys);
|
|
||||||
|
|
||||||
QJsonObject easingIn = keyframe.value(QStringLiteral("i")).toObject();
|
|
||||||
QJsonObject easingOut = keyframe.value(QStringLiteral("o")).toObject();
|
|
||||||
|
|
||||||
easingCurve.startFrame = startTime;
|
|
||||||
easingCurve.startValue = s;
|
|
||||||
if (!endValues.isEmpty()) {
|
|
||||||
qreal xe, ye;
|
|
||||||
xe = endValues.at(0).toDouble();
|
|
||||||
ye = endValues.at(1).toDouble();
|
|
||||||
T e(xe, ye);
|
|
||||||
easingCurve.endValue = e;
|
|
||||||
easingCurve.state = EasingSegmentState::Complete;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (easingIn.value(QStringLiteral("x")).isArray()) {
|
|
||||||
QJsonArray eixArr = easingIn.value(QStringLiteral("x")).toArray();
|
|
||||||
QJsonArray eiyArr = easingIn.value(QStringLiteral("y")).toArray();
|
|
||||||
|
|
||||||
QJsonArray eoxArr = easingOut.value(QStringLiteral("x")).toArray();
|
|
||||||
QJsonArray eoyArr = easingOut.value(QStringLiteral("y")).toArray();
|
|
||||||
|
|
||||||
if (!eixArr.isEmpty() && !eiyArr.isEmpty()) {
|
|
||||||
qreal eix = eixArr.takeAt(0).toDouble();
|
|
||||||
qreal eiy = eiyArr.takeAt(0).toDouble();
|
|
||||||
|
|
||||||
qreal eox = eoxArr.takeAt(0).toDouble();
|
|
||||||
qreal eoy = eoyArr.takeAt(0).toDouble();
|
|
||||||
|
|
||||||
QPointF c1 = QPointF(eox, eoy);
|
|
||||||
QPointF c2 = QPointF(eix, eiy);
|
|
||||||
|
|
||||||
easingCurve.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qreal eix = easingIn.value(QStringLiteral("x")).toDouble();
|
|
||||||
qreal eiy = easingIn.value(QStringLiteral("y")).toDouble();
|
|
||||||
|
|
||||||
qreal eox = easingOut.value(QStringLiteral("x")).toDouble();
|
|
||||||
qreal eoy = easingOut.value(QStringLiteral("y")).toDouble();
|
|
||||||
|
|
||||||
QPointF c1 = QPointF(eox, eoy);
|
|
||||||
QPointF c2 = QPointF(eix, eiy);
|
|
||||||
|
|
||||||
easingCurve.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return easingCurve;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -51,15 +51,9 @@ QT_BEGIN_NAMESPACE
|
||||||
class BMSpatialProperty : public BMProperty2D<QPointF>
|
class BMSpatialProperty : public BMProperty2D<QPointF>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void construct(const QJsonObject &definition) override
|
|
||||||
{
|
|
||||||
qCDebug(lcLottieQtBodymovinParser) << "BMSpatialProperty::construct()";
|
|
||||||
BMProperty2D<QPointF>::construct(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void postprocessEasingCurve(
|
virtual void postprocessEasingCurve(
|
||||||
EasingSegment<QPointF> &easing,
|
EasingSegment<QPointF> &easing,
|
||||||
const QJsonObject keyframe) override {
|
const QJsonObject &keyframe) override {
|
||||||
// No need to parse further incomplete keyframes (i.e. last keyframes)
|
// No need to parse further incomplete keyframes (i.e. last keyframes)
|
||||||
if (easing.state != EasingSegmentState::Complete) {
|
if (easing.state != EasingSegmentState::Complete) {
|
||||||
return;
|
return;
|
||||||
|
@ -83,15 +77,14 @@ public:
|
||||||
c1 += s;
|
c1 += s;
|
||||||
c2 += e;
|
c2 += e;
|
||||||
|
|
||||||
easing.bezier.moveTo(s);
|
QBezier bezier = QBezier::fromPoints(s, c1, c2, e);
|
||||||
easing.bezier.cubicTo(c1, c2, e);
|
|
||||||
|
|
||||||
const auto kCount = 150;
|
const auto kCount = 150;
|
||||||
easing.bezierPoints.reserve(kCount);
|
easing.bezierPoints.reserve(kCount);
|
||||||
for (auto k = 0; k < kCount; ++k) {
|
for (auto k = 0; k < kCount; ++k) {
|
||||||
const auto percent = double(k) / (kCount - 1.);
|
const auto percent = double(k) / (kCount - 1.);
|
||||||
auto point = EasingSegment<QPointF>::BezierPoint();
|
auto point = EasingSegment<QPointF>::BezierPoint();
|
||||||
point.point = easing.bezier.pointAtPercent(percent);
|
point.point = bezier.pointAt(percent);
|
||||||
if (k > 0) {
|
if (k > 0) {
|
||||||
const auto delta = (point.point - easing.bezierPoints[k - 1].point);
|
const auto delta = (point.point - easing.bezierPoints[k - 1].point);
|
||||||
point.length = std::sqrt(QPointF::dotProduct(delta, delta));
|
point.length = std::sqrt(QPointF::dotProduct(delta, delta));
|
||||||
|
|
Loading…
Reference in New Issue