if (mData && mData->mTransform) {
// update the matrix and the flag
- if ((flag & DirtyFlagBit::Matrix) ||
- !mData->mTransform->staticMatrix()) {
+ if ((flag & DirtyFlagBit::Matrix) || !mData->mTransform->isStatic()) {
newFlag |= DirtyFlagBit::Matrix;
}
m = mData->mTransform->matrix(frameNo);
return m;
}
-VMatrix LOTTransformData::matrix(int frameNo, bool autoOrient) const
-{
- if (mStaticMatrix)
- return mCachedMatrix;
- else
- return computeMatrix(frameNo, autoOrient);
-}
-
-void LOTTransformData::cacheMatrix()
-{
- mCachedMatrix = computeMatrix(0);
-}
-
-VMatrix LOTTransformData::computeMatrix(int frameNo, bool autoOrient) const
+VMatrix TransformData::matrix(int frameNo, bool autoOrient) const
{
VMatrix m;
- VPointF position = mPosition.value(frameNo);
+ VPointF position;
if (mSeparate) {
position.setX(mX.value(frameNo));
position.setY(mY.value(frameNo));
+ } else {
+ position = mPosition.value(frameNo);
}
float angle = autoOrient ? mPosition.angle(frameNo) : 0;
- if (ddd()) {
+ if (m3D) {
m.translate(position)
- .rotate(mRotation.value(frameNo))
- .rotate(angle)
- .rotate(m3D->mRz.value(frameNo))
+ .rotate(m3D->mRz.value(frameNo) + angle)
.rotate(m3D->mRy.value(frameNo), VMatrix::Axis::Y)
.rotate(m3D->mRx.value(frameNo), VMatrix::Axis::X)
.scale(mScale.value(frameNo) / 100.f)
.translate(-mAnchor.value(frameNo));
} else {
m.translate(position)
- .rotate(mRotation.value(frameNo))
- .rotate(angle)
+ .rotate(mRotation.value(frameNo) + angle)
.scale(mScale.value(frameNo) / 100.f)
.translate(-mAnchor.value(frameNo));
}
{
public:
LOTAnimatable() { construct(impl.mValue, {}); }
- LOTAnimatable(T value) { construct(impl.mValue, std::move(value)); }
+ explicit LOTAnimatable(T value) { construct(impl.mValue, std::move(value)); }
const LOTAnimInfo<T>& animation() const {return *(impl.mAnimInfo.get());}
const T& value() const {return impl.mValue;}
LOTAnimatable<float> mRz{0};
};
-class LOTTransformData : public LOTData
+struct TransformData
{
-public:
- LOTTransformData():LOTData(LOTData::Type::Transform),mScale({100, 100}){}
VMatrix matrix(int frameNo, bool autoOrient = false) const;
- float opacity(int frameNo) const { return mOpacity.value(frameNo)/100;}
- void cacheMatrix();
- bool staticMatrix() const {return mStaticMatrix;}
- bool ddd() const {return m3D ? true : false;}
-private:
- VMatrix computeMatrix(int frameNo, bool autoOrient = false) const;
-public:
+ float opacity(int frameNo) const { return mOpacity.value(frameNo)/100.0f; }
+ bool isStatic() const { return mStatic;}
std::unique_ptr<LOT3DData> m3D;
LOTAnimatable<float> mRotation{0}; /* "r" */
- LOTAnimatable<VPointF> mScale; /* "s" */
+ LOTAnimatable<VPointF> mScale{{100, 100}}; /* "s" */
LOTAnimatable<VPointF> mPosition; /* "p" */
LOTAnimatable<float> mX{0};
LOTAnimatable<float> mY{0};
LOTAnimatable<VPointF> mAnchor; /* "a" */
LOTAnimatable<float> mOpacity{100}; /* "o" */
- LOTAnimatable<float> mSkew{0}; /* "sk" */
- LOTAnimatable<float> mSkewAxis{0}; /* "sa" */
- bool mStaticMatrix{true};
bool mSeparate{false};
- VMatrix mCachedMatrix;
+ bool mStatic{false};
+};
+
+class LOTTransformData : public LOTData
+{
+public:
+ LOTTransformData():LOTData(LOTData::Type::Transform){}
+ void set(std::unique_ptr<TransformData> data)
+ {
+ setStatic(data->isStatic());
+ if (isStatic()) {
+ new (&impl.mStaticData) static_data(data->matrix(0), data->opacity(0));
+ } else {
+ new (&impl.mData) std::unique_ptr<TransformData>(std::move(data));
+ }
+ }
+ VMatrix matrix(int frameNo, bool autoOrient = false) const
+ {
+ if (isStatic()) return impl.mStaticData.mMatrix;
+ return impl.mData->matrix(frameNo, autoOrient);
+ }
+ float opacity(int frameNo) const
+ {
+ if (isStatic()) return impl.mStaticData.mOpacity;
+ return impl.mData->opacity(frameNo);
+ }
+
+ LOTTransformData& operator=(LOTTransformData&&) = delete;
+ ~LOTTransformData() {destroy();}
+
+private:
+ void destroy() {
+ if (isStatic()) {
+ impl.mStaticData.~static_data();
+ } else {
+ using std::unique_ptr;
+ impl.mData.~unique_ptr<TransformData>();
+ }
+ }
+ struct static_data {
+ static_data(VMatrix &&m, float opacity):
+ mOpacity(opacity), mMatrix(std::move(m)){}
+ float mOpacity;
+ VMatrix mMatrix;
+ };
+ union details {
+ std::unique_ptr<TransformData> mData;
+ static_data mStaticData;
+ details(){}
+ ~details(){}
+ }impl;
};
class LOTLayerData : public LOTGroupData
{
std::shared_ptr<LOTTransformData> sharedTransform =
std::make_shared<LOTTransformData>();
- LOTTransformData *obj = sharedTransform.get();
+ auto obj = std::make_unique<TransformData>();
if (ddd) obj->m3D = std::make_unique<LOT3DData>();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "nm")) {
- obj->mName = GetString();
+ sharedTransform->mName = GetString();
} else if (0 == strcmp(key, "a")) {
parseProperty(obj->mAnchor);
} else if (0 == strcmp(key, "p")) {
parseProperty(obj->mRotation);
} else if (0 == strcmp(key, "s")) {
parseProperty(obj->mScale);
- } else if (0 == strcmp(key, "sk")) {
- parseProperty(obj->mSkew);
- } else if (0 == strcmp(key, "sa")) {
- parseProperty(obj->mSkewAxis);
} else if (0 == strcmp(key, "o")) {
parseProperty(obj->mOpacity);
} else if (0 == strcmp(key, "hd")) {
- obj->mHidden = GetBool();
+ sharedTransform->mHidden = GetBool();
} else if (0 == strcmp(key, "rx")) {
parseProperty(obj->m3D->mRx);
} else if (0 == strcmp(key, "ry")) {
Skip(key);
}
}
- obj->mStaticMatrix = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
- obj->mRotation.isStatic() && obj->mScale.isStatic() &&
- obj->mSkew.isStatic() && obj->mSkewAxis.isStatic() &&
- obj->mX.isStatic() && obj->mY.isStatic();
+ obj->mStatic = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
+ obj->mRotation.isStatic() && obj->mScale.isStatic() &&
+ obj->mX.isStatic() && obj->mY.isStatic() &&
+ obj->mOpacity.isStatic();
if (obj->m3D) {
- obj->mStaticMatrix = obj->mStaticMatrix && obj->m3D->mRx.isStatic() &&
- obj->m3D->mRy.isStatic() &&
- obj->m3D->mRz.isStatic();
+ obj->mStatic = obj->mStatic && obj->m3D->mRx.isStatic() &&
+ obj->m3D->mRy.isStatic() && obj->m3D->mRz.isStatic();
}
- obj->setStatic(obj->mStaticMatrix && obj->mOpacity.isStatic());
-
- if (obj->mStaticMatrix) obj->cacheMatrix();
+ sharedTransform->set(std::move(obj));
return sharedTransform;
}