1. compute start and end with offset in the model before returning the segment.
2. modify pathmesure object to only handle start and end.
Change-Id: I8db4c2f818e8ef8c777bf1618aa143a83dabb5c0
if (mCache.mFrameNo == frameNo) return;
- float start = mData->start(frameNo);
- float end = mData->end(frameNo);
- float offset = mData->offset(frameNo);
+ LOTTrimData::Segment segment = mData->segment(frameNo);
- if (!(vCompare(mCache.mStart, start) && vCompare(mCache.mEnd, end) &&
- vCompare(mCache.mOffset, offset))) {
+ if (!(vCompare(mCache.mSegment.start, segment.start) &&
+ vCompare(mCache.mSegment.end, segment.end))) {
mDirty = true;
- mCache.mStart = start;
- mCache.mEnd = end;
- mCache.mOffset = offset;
+ mCache.mSegment = segment;
}
mCache.mFrameNo = frameNo;
}
// when both path and trim are not dirty
if (!(mDirty || pathDirty())) return;
- if (vCompare(mCache.mStart, mCache.mEnd)) {
+ if (vCompare(mCache.mSegment.start, mCache.mSegment.end)) {
for (auto &i : mPathItems) {
i->updatePath(VPath());
}
if (mData->type() == LOTTrimData::TrimType::Simultaneously) {
for (auto &i : mPathItems) {
VPathMesure pm;
- pm.setStart(mCache.mStart);
- pm.setEnd(mCache.mEnd);
- pm.setOffset(mCache.mOffset);
+ pm.setStart(mCache.mSegment.start);
+ pm.setEnd(mCache.mSegment.end);
i->updatePath(pm.trim(i->localPath()));
}
} else { // LOTTrimData::TrimType::Individually
for (auto &i : mPathItems) {
totalLength += i->localPath().length();
}
- float offset = totalLength * mCache.mOffset;
- float start = totalLength * mCache.mStart;
- float end = totalLength * mCache.mEnd;
- start += offset;
- end +=offset;
- // normalize start, end value to 0 - totalLength
- if (fabs(start) > totalLength) start = fmod(start, totalLength);
- if (fabs(end) > totalLength) end = fmod(end, totalLength);
-
- if (start >= 0 && end >= 0) {
- if (start > end) std::swap(start, end);
- } else if ( start < 0 && end < 0) {
- start += totalLength;
- end += totalLength;
- if (start > end) std::swap(start, end);
- } else {
- // one is +ve and one is -ve so the
- // segment will be wrapped from end segment to start segment.
- // we need to split it in two segment.
- //@TODO
- return;
- }
+ float start = totalLength * mCache.mSegment.start;
+ float end = totalLength * mCache.mSegment.end;
if (start < end ) {
float curLen = 0.0;
}
struct Cache {
int mFrameNo{-1};
- float mStart{0};
- float mEnd{0};
- float mOffset{0};
+ LOTTrimData::Segment mSegment{};
};
Cache mCache;
std::vector<LOTPathDataItem *> mPathItems;
class LOTTrimData : public LOTData
{
public:
+ struct Segment {
+ float start{0};
+ float end{0};
+ };
enum class TrimType {
Simultaneously,
Individually
};
LOTTrimData():LOTData(LOTData::Type::Trim){}
- float start(int frameNo) const {return mStart.value(frameNo)/100.0f;}
- float end(int frameNo) const {return mEnd.value(frameNo)/100.0f;}
- float offset(int frameNo) const {return fmod(mOffset.value(frameNo), 360.0f)/ 360.0f;}
+ Segment segment(int frameNo) const {
+ float start = mStart.value(frameNo)/100.0f;
+ float end = mEnd.value(frameNo)/100.0f;
+ float offset = fmod(mOffset.value(frameNo), 360.0f)/ 360.0f;
+ start += offset;
+ end += offset;
+ // normalize start, end value to 0 - 1
+ if (fabs(start) > 1) start = fmod(start, 1);
+ if (fabs(end) > 1) end = fmod(end, 1);
+ Segment s;
+ if (start >= 0 && end >= 0) {
+ s.start = std::min(start, end);
+ s.end = std::max(start, end);
+ } else if (start < 0 && end < 0) {
+ start += 1;
+ end +=1;
+ s.start = std::min(start, end);
+ s.end = std::max(start, end);
+ } else {
+ // one of them is -ve so it a loop
+ if (start < 0) start +=1;
+ if (end < 0) end +=1;
+ s.start = std::max(start, end);
+ s.end = std::min(start, end);
+ }
+ return s;
+
+ }
LOTTrimData::TrimType type() const {return mTrimType;}
public:
LOTAnimatable<float> mStart{0};
V_BEGIN_NAMESPACE
-VPath oneSegment(float start, float end, const VPath & path)
-{
- if (start > end) {
- std::swap(start, end);
- }
- float array[5] = {0.0f, start, end - start, std::numeric_limits<float>::max(), 0.0f};
- VDasher dasher(array, 5);
- return dasher.dashed(path);
-}
-
+/*
+ * start and end value must be normalized to [0 - 1]
+ * Path mesure trims the path from [start --> end]
+ * if start > end it treates as a loop and trims as two segment
+ * [0-->end] and [start --> 1]
+ */
VPath VPathMesure::trim(const VPath &path)
{
if (vCompare(mStart, mEnd)) return VPath();
if ((vCompare(mStart, 0.0f) && (vCompare(mEnd, 1.0f))) ||
(vCompare(mStart, 1.0f) && (vCompare(mEnd, 0.0f)))) return path;
- if (vIsZero(mOffset)) {
- float length = path.length();
- return oneSegment(length * mStart, length * mEnd, path);
- } else {
- float length = path.length();
- float offset = length * mOffset;
- float start = length * mStart;
- float end = length * mEnd;
- start += offset;
- end +=offset;
+ float length = path.length();
- if (start < 0 && end < 0) {
- return oneSegment(length + start, length + end, path);
- } else if (start > 0 && end > 0) {
- if (start > length && end > length)
- return oneSegment(start - length, end - length, path);
- else if (start < length && end < length)
- return oneSegment(start, end, path);
- else {
- float len1 = start > end ? start - length : end - length;
- float start2 = start < end ? start : end;
- float gap1 = start2 - len1;
- float array[5] = {len1, gap1, length - start2, 1000, 0.0f};
- VDasher dasher(array, 5);
- return dasher.dashed(path);
- }
- } else {
- float len1 = start > end ? start : end;
- float start2 = start < end ? length + start : length + end;
- float gap1 = start2 - len1;
- float array[5] = {len1, gap1, length - start2, 1000, 0.0f};
- VDasher dasher(array, 5);
- return dasher.dashed(path);
- }
+ if (mStart < mEnd) {
+ float array[4] = {0.0f, length * mStart, //1st segment
+ (mEnd - mStart) * length, std::numeric_limits<float>::max(), //2nd segment
+ };
+ VDasher dasher(array, 4);
+ return dasher.dashed(path);
+ } else {
+ float array[4] = {length * mEnd, (mStart - mEnd) * length, //1st segment
+ (1 - mStart) * length, std::numeric_limits<float>::max(), //2nd segment
+ };
+ VDasher dasher(array, 4);
+ return dasher.dashed(path);
}
}
public:
void setStart(float start){mStart = start;}
void setEnd(float end){mEnd = end;}
- void setOffset(float offset){mOffset = offset;}
VPath trim(const VPath &path);
private:
float mStart{0.0f};
float mEnd{1.0f};
- float mOffset{0.0f};
};
V_END_NAMESPACE